diff --git a/pom.xml b/pom.xml
index dc51a9b..817de48 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,10 +28,11 @@
org.springframework.boot
spring-boot-starter-freemarker
-
+
org.springframework.boot
spring-boot-starter-security
- -->
+
org.springframework.boot
spring-boot-starter-web
@@ -46,16 +47,6 @@
h2
runtime
-
-
org.json
@@ -109,9 +100,6 @@
org.springframework.boot
spring-boot-maven-plugin
-
- false
-
diff --git a/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java b/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java
new file mode 100644
index 0000000..5f95448
--- /dev/null
+++ b/src/main/java/com/yaoyuan/jiscuss/config/WebSecurityConfig.java
@@ -0,0 +1,98 @@
+package com.yaoyuan.jiscuss.config;
+
+import com.yaoyuan.jiscuss.handler.CustomAccessDeniedHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+/**
+prePostEnabled :决定Spring Security的前注解是否可用 [@PreAuthorize,@PostAuthorize,..]
+secureEnabled : 决定是否Spring Security的保障注解 [@Secured] 是否可用
+jsr250Enabled :决定 JSR-250 annotations 注解[@RolesAllowed..] 是否可用.
+ */
+@Configurable
+@EnableWebSecurity
+//开启 Spring Security 方法级安全注解 @EnableGlobalMethodSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
+
+ @Autowired
+ private CustomAccessDeniedHandler customAccessDeniedHandler;
+ @Qualifier("userDetailServiceImpl")
+ @Autowired
+ private UserDetailsService userDetailsService;
+
+ /**
+ * 静态资源设置
+ */
+ @Override
+ public void configure(WebSecurity webSecurity) {
+ //不拦截静态资源,所有用户均可访问的资源
+ webSecurity.ignoring().antMatchers(
+ "/",
+ "/css/**",
+ "/js/**",
+ "/images/**",
+ "/static/**",
+ "/index/**"
+ );
+ }
+ /**
+ * http请求设置
+ */
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ //http.csrf().disable(); //注释就是使用 csrf 功能
+ http.headers().frameOptions().disable();//解决 in a frame because it set 'X-Frame-Options' to 'DENY' 问题
+ //http.anonymous().disable();
+ http.authorizeRequests()
+ .antMatchers("/login/**","/initUserData")//不拦截登录相关方法
+ .permitAll()
+ //.antMatchers("/user").hasRole("ADMIN") // user接口只有ADMIN角色的可以访问
+// .anyRequest()
+// .authenticated()// 任何尚未匹配的URL只需要验证用户即可访问
+ .anyRequest()
+ .access("@rbacPermission.hasPermission(request, authentication)")//根据账号权限访问
+ .and()
+ .formLogin()
+// .loginPage("/")
+ .loginPage("/login") //登录请求页
+ .loginProcessingUrl("/login") //登录POST请求路径
+ .usernameParameter("username") //登录用户名参数
+ .passwordParameter("password") //登录密码参数
+ .defaultSuccessUrl("/") //默认登录成功页面
+ .and()
+ .exceptionHandling()
+ .accessDeniedHandler(customAccessDeniedHandler) //无权限处理器
+ .and()
+ .logout()
+ .logoutSuccessUrl("/login?logout"); //退出登录成功URL
+
+ }
+ /**
+ * 自定义获取用户信息接口
+ */
+ @Override
+ public void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
+ }
+
+ /**
+ * 密码加密算法
+ * @return
+ */
+ @Bean
+ public BCryptPasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+
+ }
+}
diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
index d233c38..6fb0dd2 100644
--- a/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
+++ b/src/main/java/com/yaoyuan/jiscuss/controller/UserSystemController.java
@@ -11,17 +11,20 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@@ -51,7 +54,29 @@ public class UserSystemController {
List useral2 = usersService.getAllList();
logger.info(">>> 第二遍的全部用户:"+useral2);
-
+
+ String username ="";
+ //获得session对象
+ HttpSession session = request.getSession();
+ //取出session域中所有属性名
+ Enumeration attributeNames = session.getAttributeNames();
+ while (attributeNames.hasMoreElements()) {
+ System.out.println(attributeNames.nextElement());
+ }
+ //SPRING_SECURITY_CONTEXT
+ Object spring_security_context = session.getAttribute("SPRING_SECURITY_CONTEXT");
+ System.out.println(spring_security_context);
+ SecurityContext securityContext = (SecurityContext) spring_security_context;
+ if(securityContext!=null){
+ //获得认证信息
+ Authentication authentication = securityContext.getAuthentication();
+ //获得用户详情
+ Object principal = authentication.getPrincipal();
+ User user = (User) principal;
+ username = user.getUsername();
+ System.out.println(username);
+ }
+
//分页获取主题帖子
// List allDiscussions = discussionsService.getAllList();
@@ -63,19 +88,17 @@ public class UserSystemController {
//获取主题帖子的分页数据
List pageNumList = getPageNumList(allDiscussionsPage.getTotalPages());
-
-
+
//获取所有标签(以后尝试去缓存中取)
List allTags = tagsService.getAllList();
logger.info("全部标签==>:{}",allTags);
- HttpSession session=request.getSession();
System.out.println(userall.toString());
map.put("data", "Jiscuss 用户");
map.put("allDiscussions", allDiscussions);
map.put("pageDiscussions", pageNumList);
map.put("allTags", allTags);
- map.put("username", session.getAttribute("username"));
+ map.put("username", username);
return "index";
}
@@ -99,25 +122,41 @@ public class UserSystemController {
//登录
- @PostMapping(value = "/login")
- @ResponseBody
- public String login(@RequestParam("username") String username, @RequestParam("password") String password,
- HttpSession session) {
- JSONObject resultobj = new JSONObject();
- Users user = usersService.checkByUsernameAndPassword(username, password);
- if (user!=null) {
- //用户名和密码完成校验
- session.setAttribute("username", username); //缓存session
- session.setAttribute("userid", user.getId()); //缓存session
- resultobj.put("username", username);
- resultobj.put("msg", "登录成功");
- resultobj.put("flag", true);
- } else {
- //用户名和密码未完成校验
- resultobj.put("msg", "用户名或密码错误");
- resultobj.put("flag", false);
+// @PostMapping(value = "/login")
+// @ResponseBody
+// public String login(@RequestParam("username") String username, @RequestParam("password") String password,
+// HttpSession session) {
+// JSONObject resultobj = new JSONObject();
+// Users user = usersService.checkByUsernameAndPassword(username, password);
+// if (user!=null) {
+// //用户名和密码完成校验
+// session.setAttribute("username", username); //缓存session
+// session.setAttribute("userid", user.getId()); //缓存session
+// resultobj.put("username", username);
+// resultobj.put("msg", "登录成功");
+// resultobj.put("flag", true);
+// } else {
+// //用户名和密码未完成校验
+// resultobj.put("msg", "用户名或密码错误");
+// resultobj.put("flag", false);
+// }
+// return resultobj.toString();
+// }
+
+ //登录页
+ @GetMapping("/login")
+ public String login(@RequestParam(value = "error", required = false) String error,
+ @RequestParam(value = "logout", required = false) String logout,Map map) {
+ if (error != null) {
+ map.put("msg", "您输入的用户名密码错误!");
+ return "login";
}
- return resultobj.toString();
+ if (logout != null) {
+ map.put("msg", "退出成功!");
+ return "login";
+ }
+
+ return "login";
}
//退出
diff --git a/src/main/java/com/yaoyuan/jiscuss/entity/Users.java b/src/main/java/com/yaoyuan/jiscuss/entity/Users.java
index 27aac52..32fc408 100644
--- a/src/main/java/com/yaoyuan/jiscuss/entity/Users.java
+++ b/src/main/java/com/yaoyuan/jiscuss/entity/Users.java
@@ -3,7 +3,9 @@ package com.yaoyuan.jiscuss.entity;
import java.io.Serializable;
+import java.util.Collection;
import java.util.Date;
+import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -16,11 +18,13 @@ import javax.persistence.Table;
import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
@Data
@Entity
@Table(name="users")
-public class Users implements Serializable {
+public class Users implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@@ -65,7 +69,5 @@ public class Users implements Serializable {
@Column(name="level")
private Integer level;
-
-
-
+
}
\ No newline at end of file
diff --git a/src/main/java/com/yaoyuan/jiscuss/handler/CustomAccessDeniedHandler.java b/src/main/java/com/yaoyuan/jiscuss/handler/CustomAccessDeniedHandler.java
new file mode 100644
index 0000000..677e001
--- /dev/null
+++ b/src/main/java/com/yaoyuan/jiscuss/handler/CustomAccessDeniedHandler.java
@@ -0,0 +1,64 @@
+package com.yaoyuan.jiscuss.handler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.WebAttributes;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * 处理无权请求
+ * @author charlie
+ *
+ */
+@Component
+public class CustomAccessDeniedHandler implements AccessDeniedHandler {
+
+ private Logger log = LoggerFactory.getLogger(CustomAccessDeniedHandler.class);
+
+ @Override
+ public void handle(HttpServletRequest request, HttpServletResponse response,
+ AccessDeniedException accessDeniedException) throws IOException, ServletException {
+ boolean isAjax = ControllerTools.isAjaxRequest(request);
+ System.out.println("CustomAccessDeniedHandler handle");
+ if (!response.isCommitted()) {
+ if (isAjax) {
+ String msg = accessDeniedException.getMessage();
+ log.info("accessDeniedException.message:" + msg);
+ String accessDenyMsg = "{\"code\":\"403\",\"msg\":\"没有权限\"}";
+ ControllerTools.print(response, accessDenyMsg);
+ } else {
+ request.setAttribute(WebAttributes.ACCESS_DENIED_403, accessDeniedException);
+ response.setStatus(HttpStatus.FORBIDDEN.value());
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/403");
+ dispatcher.forward(request, response);
+ }
+ }
+
+ }
+
+ public static class ControllerTools {
+ public static boolean isAjaxRequest(HttpServletRequest request) {
+ return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
+ }
+
+ public static void print(HttpServletResponse response, String msg) throws IOException {
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("application/json; charset=utf-8");
+ PrintWriter writer = response.getWriter();
+ writer.write(msg);
+ writer.flush();
+ writer.close();
+ }
+ }
+
+}
diff --git a/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java b/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java
new file mode 100644
index 0000000..c08168b
--- /dev/null
+++ b/src/main/java/com/yaoyuan/jiscuss/handler/RbacPermission.java
@@ -0,0 +1,38 @@
+package com.yaoyuan.jiscuss.handler;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+import org.springframework.util.AntPathMatcher;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * RBAC数据模型控制权限
+ * @author charlie
+ *
+ */
+@Component("rbacPermission")
+public class RbacPermission{
+
+ private AntPathMatcher antPathMatcher = new AntPathMatcher();
+
+ public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
+ Object principal = authentication.getPrincipal();
+ boolean hasPermission = false;
+
+ hasPermission = true;
+// if (principal instanceof UserEntity) {
+// // 读取用户所拥有的权限菜单
+// List