增加sepringsecurity样例

This commit is contained in:
fxb 2018-08-01 22:15:19 +08:00
parent 0e89e429b5
commit cc974943f2
36 changed files with 1583 additions and 0 deletions

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot_spirngsecurity_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot_spirngsecurity_demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,24 @@
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.example.demo.mapper")
public class SpringbootSpirngsecurityDemoApplication extends WebMvcConfigurationSupport {
public static void main(String[] args) {
SpringApplication.run(SpringbootSpirngsecurityDemoApplication.class, args);
}
@Override
protected void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false) //设置路由是否后缀匹配譬如/user能够匹配/user.,/user.aa
.setUseTrailingSlashMatch(false); //设置是否后缀路径匹配比如/user能够匹配/user,/user/
}
}

View File

@ -0,0 +1,33 @@
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.util.Reply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PublicController {
@Autowired
private UserService userService;
private Logger log = LoggerFactory.getLogger(this.getClass());
//注册账号
@PostMapping("/public/register")
public Reply register(User user) {
userService.register(user);
return new Reply("注册成功");
}
// //未登录提示错误
// @GetMapping("/public/unlogin")
// public Reply unLoginError() {
// ErrorCode code= ErrorCode.UNLOGIN;
// return new Reply(code.getCode(),code.getMess());
// }
}

View File

@ -0,0 +1,37 @@
package com.example.demo.controller;
import com.example.demo.service.UserService;
import com.example.demo.util.Reply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
//获取用户列表
@GetMapping("/user")
public Object getAllUser(){
return new Reply(userService.getAll());
}
@GetMapping("/user/{userId}")
public Object getOne(@PathVariable int userId){
return new Reply(userService.getOne(userId));
}
@GetMapping("/user/{userId}/12")
public Object getTwo(@PathVariable int userId){
return new Reply(userService.getOne(userId));
}
@PostMapping("/user")
public void insert(){
userService.insert();
}
}

View File

@ -0,0 +1,59 @@
package com.example.demo.entity;
public class Jurisdiction {
private int id;
private String permission;
private String description;
private String url;
private String method;
public Jurisdiction() {}
public Jurisdiction(int id, String permission, String description, String url, String method) {
this.id = id;
this.permission = permission;
this.description = description;
this.url = url;
this.method = method;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,33 @@
package com.example.demo.entity;
public class Role {
private int id;
private String name;
public Role() {
}
public Role(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,103 @@
package com.example.demo.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class User implements UserDetails{
private static final long serialVersionUID = 1L;
private int id;
private String password;
private String name;
private short age;
List<GrantedAuthority> authorities;
public User() {
}
public User(int id,String password, String name,short age) {
this.id = id;
this.password = password;
this.name = name;
this.age = age;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public short getAge() {
return age;
}
public void setAge(short age) {
this.age = age;
}
public void setAuthorities(List<GrantedAuthority> authorities) {
this.authorities = authorities;
}
@Override
public String toString() {
return "User [id=" + id + ", password=" + password + ", name=" + name + ", age=" + age + "]";
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getUsername() {
return String.valueOf(this.id);
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -0,0 +1,27 @@
package com.example.demo.error;
public enum ErrorCode {
OK(0,"正常"),
UNLOGIN(1,"未登录"),
NO_PERMISSION(2,"无操作权限"),
SERVICE_ERROR(3,"服务发生错误"),
BAD_REQUEST(4,"请求无法执行"),
HAD_LOGIN(5,"已登录"),
WRONG_LOGIN_INFO(6,"账号密码错误"),
UNKONWN_ERROR(555,"其他错误");
private final int code;
private final String mess;
private ErrorCode(int code,String mess) {
this.code = code;
this.mess = mess;
}
public int getCode() {
return code;
}
public String getMess() {
return mess;
}
}

View File

@ -0,0 +1,39 @@
package com.example.demo.error;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.example.demo.util.Reply;
@RestControllerAdvice
public class ExceptionHandle {
private static final Logger log = LoggerFactory.getLogger(ExceptionHandle.class);
// 运行时异常捕捉
@ExceptionHandler(RuntimeException.class)
public Object handleRuntionException(RuntimeException e) {
if (e instanceof HttpMessageConversionException) {
log.error("bad request:{},{}", e.getMessage(), e);
return new Reply(ErrorCode.BAD_REQUEST.getCode(), "参数无法理解");
}
if (e instanceof ServiceError) {
log.error("业务错误:{},{}", e.getMessage(), e);
return new Reply(((ServiceError) e).getErrorCode(), e.getMessage());
}
if (e instanceof RuntimeException) {
return new Reply(ErrorCode.SERVICE_ERROR.getCode(),e.getMessage() );
}
log.error("其他错误:{}{}", e.getMessage(), e);
return new Reply(ErrorCode.UNKONWN_ERROR.getCode(), "未知错误");
}
// 全局异常捕捉
@ExceptionHandler(Exception.class)
public Object handleException(Exception e) {
log.error("未处理异常:{}\n{}", e.getMessage(), e);
return new Reply(ErrorCode.UNKONWN_ERROR.getCode(), "未处理异常");
}
}

View File

@ -0,0 +1,30 @@
package com.example.demo.error;
public class ServiceError extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
private int errorCode;
public ServiceError(String message) {
super(message);
this.errorCode = ErrorCode.SERVICE_ERROR.getCode();
}
public ServiceError(int code,String message) {
super(message);
this.errorCode = code;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}

View File

@ -0,0 +1,22 @@
package com.example.demo.error;
public class UnloginError extends RuntimeException {
private static final long serialVersionUID = 1L;
private int errorCode;
public UnloginError() {
super("未登录");
this.errorCode=ErrorCode.UNLOGIN.getCode();
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}

View File

@ -0,0 +1,36 @@
package com.example.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.example.demo.entity.Jurisdiction;
public interface JurisdictionMapper {
@Select("select * from Jurisdiction")
public List<Jurisdiction> selectAllPermission();
@Insert("insert into jurisdiction(permission,description) value(#{permission},#{description})")
@Options(useGeneratedKeys=true,keyColumn="id",keyProperty="id")
public void addOne(Jurisdiction jurisdiction);
@Delete("delete from jurisdiction where id=#{id}")
public boolean deleteOne(int id);
@Update("update jurisdiction set permission=#{permission},description = #{description} where id=#{id}")
public boolean update(Jurisdiction jurisdiction);
//查找某角色所有权限
@Select("SELECT b.* FROM RoleJurisdictionRelation a INNER JOIN jurisdiction b ON a.j_id = b.id WHERE a.r_id =#{id}")
public List<Jurisdiction> selectByRoleId(int id);
//查找某用户所有权限
@Select("SELECT c.* FROM UserRoleRelation a INNER JOIN RoleJurisdictionRelation b ON a.r_id = b.r_id INNER JOIN Jurisdiction c ON b.j_id = c.id WHERE a.u_id =#{id}")
public List<Jurisdiction> selectByUserId(int id);
}

View File

@ -0,0 +1,12 @@
package com.example.demo.mapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
public interface RoleJurisdictionMapper {
@Delete("delete from roleJurisdictionRelation where r_id=#{id}")
public void deleteByRoleId(int id);
@Insert("insert into roleJurisdictionRelation(r_id,j_id) value(#{roleId},#{jId})")
public void insert(int roleId,int jId);
}

View File

@ -0,0 +1,30 @@
package com.example.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.example.demo.entity.Role;
public interface RoleMapper {
@Select("select * from role")
public List<Role> selectAllRole();
@Select("SELECT b.* from UserRoleRelation a INNER JOIN Role b on a.r_id = b.id where a.u_id = #{userId}")
public List<Role> selectByUserId(int userId);
@Insert("insert into role(name) value(#{name})")
@Options(useGeneratedKeys=true,keyProperty="id",keyColumn="id")
public void addOne(Role role);
@Delete("delete from role where id=#{id}")
public boolean deleteOne(int id);
@Update("update role set name=#{name} where id=#{id}")
public boolean updateName(int id, String name);
}

View File

@ -0,0 +1,34 @@
package com.example.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.example.demo.entity.User;
public interface UserMapper {
//新增用户
@Insert("insert into user(name,age,password) value(#{name},#{age},#{password})")
@Options(useGeneratedKeys=true,keyColumn="id",keyProperty="id")
public void insert(User user);
//查找所有用户
@Select("select * from user")
public List<User> getAll();
//根据id查找用户
@Select("select * from user where id=#{id}")
public User getById(int id);
@Update("update user set name=#{name},age=#{age},password=#{password} where id=#{id}")
public boolean update(User user);
//根据id删除用户
@Delete("delete from user where id=#{id}")
public boolean deleteById(int id);
}

View File

@ -0,0 +1,16 @@
package com.example.demo.mapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
public interface UserRoleMapper {
@Delete("delete from userRoleRelation where u_id=#{id}")
public void deleteByUserId(int id);
@Insert("insert into userRoleRelation(u_id,r_id) value(#{userId},#{roleId})")
public void insert(int userId,int roleId);
//根据角色名给用户分配角色
@Insert("insert into userrolerelation select #{userId},id from role where name=#{roleName}")
public void insertByRoleName(int userId,String roleName);
}

View File

@ -0,0 +1,38 @@
package com.example.demo.security;
import com.example.demo.error.ErrorCode;
import com.example.demo.util.JsonHelper;
import com.example.demo.util.Reply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component("myAccessDeniedHandler")
public class MyAccessDeniedHandler implements AccessDeniedHandler{
@Autowired
private JsonHelper jsonHelper;
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
log.info("吴操作权限:{}",accessDeniedException.getMessage());
response.setContentType("application/json;charset=UTF-8");
ErrorCode code = ErrorCode.NO_PERMISSION;
response.getWriter().write(jsonHelper.toJson(new Reply(code.getCode(),code.getMess())));
}
}

View File

@ -0,0 +1,32 @@
package com.example.demo.security;
import com.example.demo.error.ErrorCode;
import com.example.demo.util.JsonHelper;
import com.example.demo.util.Reply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component("myAuthFailedHandle")
public class MyAuthFailedHandle extends SimpleUrlAuthenticationFailureHandler{
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private JsonHelper jsonHelper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
ErrorCode code = ErrorCode.WRONG_LOGIN_INFO;
response.getWriter().write(jsonHelper.toJson(new Reply(code.getCode(),code.getMess()+"asdf")));
}
}

View File

@ -0,0 +1,37 @@
package com.example.demo.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.example.demo.util.JsonHelper;
import com.example.demo.util.Reply;
@Component("myAuthSuccessHandle")
public class MyAuthSuccessHandle implements AuthenticationSuccessHandler{
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private JsonHelper jsonHelper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(jsonHelper.toJson(new Reply("登录成功")));
}
}

View File

@ -0,0 +1,41 @@
package com.example.demo.security;
import com.example.demo.error.ErrorCode;
import com.example.demo.util.JsonHelper;
import com.example.demo.util.Reply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* Description:未登录直接返回401不进行302跳转
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-18
*/
@Component
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Autowired
private JsonHelper jsonHelper;
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
log.info("未登录:{}",authException.getMessage() );
ErrorCode code=ErrorCode.UNLOGIN;
authException.printStackTrace();
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(jsonHelper.toJson(new Reply(code.getCode(),code.getMess())));
}
}

View File

@ -0,0 +1,34 @@
package com.example.demo.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import com.example.demo.util.JsonHelper;
import com.example.demo.util.Reply;
@Component("myLogoutSuccessHandle")
public class MyLogoutSuccessHandle implements LogoutSuccessHandler{
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private JsonHelper jsonHelper;
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(jsonHelper.toJson(new Reply("登出成功")));
}
}

View File

@ -0,0 +1,30 @@
package com.example.demo.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.example.demo.util.StringUtil;
import org.springframework.stereotype.Component;
/**
* @author fxb 实现PasswordEncoder接口自定义加密算法自定义密码判断
*
*/
@Component
public class MyPasswordEncoder implements PasswordEncoder {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
//密码是否匹配
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
String encodeStr = StringUtil.StringToMD5(rawPassword.toString());
log.info("raw:{},encoded:{}", rawPassword.toString(), encodedPassword);
return encodedPassword.equals(encodeStr);
}
}

View File

@ -0,0 +1,32 @@
package com.example.demo.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyUsernamePasswordAuthentication extends UsernamePasswordAuthenticationFilter{
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
//验证失败抛出错误
log.info("在这里进行验证码判断");
return super.attemptAuthentication(request, response);
}
@Autowired
@Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
// TODO Auto-generated method stub
super.setAuthenticationManager(authenticationManager);
}
}

View File

@ -0,0 +1,141 @@
package com.example.demo.security;
import com.example.demo.security.authentication.MyFilterSecurityInterceptor;
import com.example.demo.service.SecurityUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private MyAuthFailedHandle myAuthFailedHandle;
@Autowired
private MyAuthSuccessHandle myAuthSuccessHandle;
@Autowired
private MyAccessDeniedHandler myAccessDeniedHandler;
@Autowired
private MyLogoutSuccessHandle myLogoutSuccessHandle;
@Autowired
private AuthenticationManagerBuilder authenticationManagerBuilder;
@Autowired
private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
@Autowired
private MyFilterSecurityInterceptor urlFilterSecurityInterceptor;
@Autowired
private SecurityUserService securityUserService;
@Autowired
private MyPasswordEncoder myPasswordEncoder;
@Autowired
DataSource dataSource;
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return this.authenticationManagerBuilder.build();
}
@Bean
public MyUsernamePasswordAuthentication myUsernamePasswordAuthentication(){
MyUsernamePasswordAuthentication myUsernamePasswordAuthentication = new MyUsernamePasswordAuthentication();
//设置登录成功处理登录失败处理
myUsernamePasswordAuthentication.setAuthenticationFailureHandler(myAuthFailedHandle);
myUsernamePasswordAuthentication.setAuthenticationSuccessHandler(myAuthSuccessHandle);
myUsernamePasswordAuthentication.setFilterProcessesUrl("/public/login");
myUsernamePasswordAuthentication.setRememberMeServices(rememberMeServices());
myUsernamePasswordAuthentication.setUsernameParameter("id");
myUsernamePasswordAuthentication.setPasswordParameter("password");
return myUsernamePasswordAuthentication;
}
// @Bean
// public UrlFilterSecurityInterceptor urlFilterSecurityInterceptor(){
// UrlFilterSecurityInterceptor urlFilterSecurityInterceptor = new UrlFilterSecurityInterceptor();
// urlFilterSecurityInterceptor.setSecurityMetadataSource(mySecurityMetadataSource);
// urlFilterSecurityInterceptor.setAccessDecisionManager(myAccessDecisionManager);
// return urlFilterSecurityInterceptor;
// }
//设置登录
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityUserService)
.passwordEncoder(myPasswordEncoder);
// auth.eraseCredentials(false);
}
@Bean
public RememberMeServices rememberMeServices(){
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
PersistentTokenBasedRememberMeServices rememberMeServices =
new PersistentTokenBasedRememberMeServices("INTERNAL_SECRET_KEY",securityUserService,jdbcTokenRepository);
// rememberMeServices.setCookieName("heiyou");
return rememberMeServices;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().maximumSessions(1).expiredUrl("/public/unlogin");
http
.csrf() //跨站
.disable() //关闭跨站检测
//自定义鉴权过程无需下面设置
// .authorizeRequests()//验证策略
// .antMatchers("/public/**").permitAll()//无需验证路径
// .antMatchers("/user/**").permitAll()
// .antMatchers("/login").permitAll()//放行登录
// .antMatchers(HttpMethod.GET, "/user").hasAuthority("getAllUser")//拥有权限才可访问
// .antMatchers(HttpMethod.GET, "/user").hasAnyAuthority("1","2")//拥有任一权限即可访问
//角色类似hasRole(),hasAnyRole()
// .anyRequest().authenticated()
// .and()
.exceptionHandling()
.authenticationEntryPoint(myAuthenticationEntryPoint)//未登录处理
.accessDeniedHandler(myAccessDeniedHandler)//权限不足处理
.and()
.addFilterBefore(myUsernamePasswordAuthentication(),UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(urlFilterSecurityInterceptor,FilterSecurityInterceptor.class)
.rememberMe()//默认放在内存中
.rememberMeServices(rememberMeServices())
.key("INTERNAL_SECRET_KEY")
// 重写usernamepasswordauthenticationFilter后下面的设置失效
// .and()
// .formLogin()
// .loginPage("/public/unlogin") //未登录跳转页面,设置了authenticationentrypoint后无需设置未登录跳转页面
// .loginProcessingUrl("/public/login")//登录api
// .successForwardUrl("/success")
// .failureForwardUrl("/failed")
// .usernameParameter("id")
// .passwordParameter("password")
// .failureHandler(myAuthFailedHandle) //登录失败处理
// .successHandler(myAuthSuccessHandle)//登录成功处理
// .usernameParameter("id")
.and()
.logout()//自定义登出
.logoutUrl("/public/logout")
// .logoutSuccessUrl("public/logoutSuccess")
.logoutSuccessHandler(myLogoutSuccessHandle);
}
}

View File

@ -0,0 +1,56 @@
package com.example.demo.security.authentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class MyAccessDecisionManager implements AccessDecisionManager{
private Logger log = LoggerFactory.getLogger(this.getClass());
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException, InsufficientAuthenticationException {
//无需验证放行
if(configAttributes==null || configAttributes.size()==0)
return;
log.info("开始验证");
// if(!authentication.isAuthenticated()){
if(authenticationTrustResolver.isAnonymous(authentication)){
throw new InsufficientAuthenticationException("未登录");
}
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for(ConfigAttribute attribute : configAttributes){
if(!(attribute instanceof MyConfigAttribute)) continue;
MyConfigAttribute urlConfigAttribute = (MyConfigAttribute)attribute;
for(GrantedAuthority authority: authorities){
if(!(authority instanceof MyGrantedAuthority)) continue;
MyGrantedAuthority myGrantedAuthority = (MyGrantedAuthority)authority;
if(urlConfigAttribute.getMyGrantedAuthority().equals(myGrantedAuthority))
return;
}
}
throw new AccessDeniedException("无权限");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}

View File

@ -0,0 +1,39 @@
package com.example.demo.security.authentication;
import org.springframework.security.access.ConfigAttribute;
import javax.servlet.http.HttpServletRequest;
/**
* Created with IntelliJ IDEA.
* Description:自定义ConfigAttribute实现
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-19
*/
public class MyConfigAttribute implements ConfigAttribute {
private HttpServletRequest httpServletRequest;
private MyGrantedAuthority myGrantedAuthority;
public MyConfigAttribute(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
public MyConfigAttribute(HttpServletRequest httpServletRequest, MyGrantedAuthority myGrantedAuthority) {
this.httpServletRequest = httpServletRequest;
this.myGrantedAuthority = myGrantedAuthority;
}
public HttpServletRequest getHttpServletRequest() {
return httpServletRequest;
}
@Override
public String getAttribute() {
return myGrantedAuthority.getUrl();
}
public MyGrantedAuthority getMyGrantedAuthority() {
return myGrantedAuthority;
}
}

View File

@ -0,0 +1,64 @@
package com.example.demo.security.authentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* Description:
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-19
*/
@Component
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Autowired
private MySecurityMetadataSource mySecurityMetadataSource;
@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.mySecurityMetadataSource;
}
}

View File

@ -0,0 +1,55 @@
package com.example.demo.security.authentication;
import org.springframework.security.core.GrantedAuthority;
/**
* Created with IntelliJ IDEA.
* Description:自定义权限类
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-19
*/
public class MyGrantedAuthority implements GrantedAuthority {
private String method;
private String url;
public MyGrantedAuthority(String method, String url) {
this.method = method;
this.url = url;
}
@Override
public String getAuthority() {
return url;
}
public String getMethod() {
return method;
}
public String getUrl() {
return url;
}
@Override
public boolean equals(Object obj) {
if(this==obj) return true;
if(obj==null||getClass()!= obj.getClass()) return false;
MyGrantedAuthority grantedAuthority = (MyGrantedAuthority)obj;
if(this.method.equals(grantedAuthority.getMethod())&&this.url.equals(grantedAuthority.getUrl()))
return true;
return false;
}
@Override
public int hashCode() {
int result = this.method!=null?this.method.hashCode():0;
result=33*result+(this.url!=null?this.url.hashCode():0);
return result;
}
@Override
public String toString() {
return this.method+" : "+this.url;
}
}

View File

@ -0,0 +1,65 @@
package com.example.demo.security.authentication;
import com.example.demo.entity.Jurisdiction;
import com.example.demo.mapper.JurisdictionMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* Description:
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-19
*/
@Component
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private JurisdictionMapper jurisdictionMapper;
private List<Jurisdiction> jurisdictions;
private void loadResource() {
log.info("get all jurisdiction");
this.jurisdictions = jurisdictionMapper.selectAllPermission();
}
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
if (jurisdictions == null) this.loadResource();
HttpServletRequest request = ((FilterInvocation) object).getRequest();
Set<ConfigAttribute> allConfigAttribute = new HashSet<>();
AntPathRequestMatcher matcher;
for (Jurisdiction jurisdiction : jurisdictions) {
matcher = new AntPathRequestMatcher(jurisdiction.getUrl(), jurisdiction.getMethod());
if (matcher.matches(request)) {
ConfigAttribute configAttribute = new MyConfigAttribute(request,new MyGrantedAuthority(jurisdiction.getMethod(),jurisdiction.getUrl()));
allConfigAttribute.add(configAttribute);
return allConfigAttribute;
}
}
return null;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}

View File

@ -0,0 +1,57 @@
package com.example.demo.service;
import com.example.demo.entity.Jurisdiction;
import com.example.demo.entity.User;
import com.example.demo.mapper.JurisdictionMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.security.authentication.MyGrantedAuthority;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* Description:
* User: ${fxb}
* Email: fanxb.tl@gmail.com
* Date: 2018-07-20
*/
@Component
public class SecurityUserService implements UserDetailsService {
@Autowired
private JurisdictionMapper jurisdictionMapper;
@Autowired
private UserMapper userMapper;
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("登录用户id为{}",username);
int id = Integer.valueOf(username);
User user = userMapper.getById(id);
if(user==null) {
log.info("登录用户id不存在{}",username);
throw new UsernameNotFoundException("用户名 "+username+"不存在");
}
//获取用户权限
List<GrantedAuthority> authorities = new ArrayList<>();
List<Jurisdiction> jurisdictions = jurisdictionMapper.selectByUserId(id);
for(Jurisdiction item : jurisdictions) {
// GrantedAuthority authority = new SimpleGrantedAuthority(item.getPermission());
GrantedAuthority authority = new MyGrantedAuthority(item.getMethod(),item.getUrl());
authorities.add(authority);
}
user.setAuthorities(authorities);
log.info("获取用户{}信息成功,权限为:{}",username,authorities);
return user;
}
}

View File

@ -0,0 +1,66 @@
package com.example.demo.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.example.demo.security.authentication.MyGrantedAuthority;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.example.demo.entity.Jurisdiction;
import com.example.demo.entity.User;
import com.example.demo.mapper.JurisdictionMapper;
import com.example.demo.mapper.RoleMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.mapper.UserRoleMapper;
import com.example.demo.util.StringUtil;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private JurisdictionMapper jurisdictionMapper;
@Autowired
private UserRoleMapper userRoleMapper;
private Logger log = LoggerFactory.getLogger(this.getClass());
//默认分配guest角色
public void register(User user) {
user.setPassword(StringUtil.StringToMD5(user.getPassword()));
log.info(user.toString());
userMapper.insert(user);
userRoleMapper.insertByRoleName(user.getId(), "guest");
}
//获取所有用户
public List<User> getAll(){
return userMapper.getAll();
}
public User getOne(int id){
User user = userMapper.getById(id);
return user;
}
//插入用户
@Transactional
public void insert(){
User user = new User(100,"123456","fxb",(short)12);
userMapper.insert(user);
user.setAge((short)1000);
userMapper.insert(user);
log.info("插入用户完毕");
}
}

View File

@ -0,0 +1,40 @@
package com.example.demo.util;
import java.io.IOException;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class JsonHelper {
private ObjectMapper mapper;
public JsonHelper() {
mapper = new ObjectMapper();
// mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public JsonHelper(JsonInclude.Include include) {
mapper = new ObjectMapper();
mapper.setSerializationInclusion(include);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public String toJson(Object object) throws JsonProcessingException {
return mapper.writeValueAsString(object);
}
public <T> T fromJson(String json, Class<T> cls) throws Exception{
return mapper.readValue(json, cls);
}
public <T> T fromJson(String json, @SuppressWarnings("rawtypes") TypeReference valueTypeRef) throws IOException {
return mapper.readValue(json, valueTypeRef);
}
}

View File

@ -0,0 +1,74 @@
package com.example.demo.util;
import com.example.demo.error.ErrorCode;
public class Reply {
private int status;
private String info;
private Object data;
public Reply() {
System.out.println("reply默认构造函数");
ErrorCode OK = ErrorCode.OK;
this.status = OK.getCode();
this.info = OK.getMess();
}
public Reply(int status, String info, Object data) {
super();
this.status = status;
this.info = info;
this.data = data;
}
public Reply(int status, String info) {
this.status = status;
this.info = info;
}
public Reply(int status) {
this.status = status;
this.info = "";
}
public Reply(String info) {
this.status = ErrorCode.OK.getCode();
this.info = info;
}
public Reply(String info, Object o) {
this.status = ErrorCode.OK.getCode();
this.info = info;
this.data = o;
}
public Reply(Object o) {
this.status = ErrorCode.OK.getCode();
this.info = ErrorCode.OK.getMess();
this.data = o;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,39 @@
package com.example.demo.util;
import java.security.MessageDigest;
import org.springframework.stereotype.Component;
@Component
public class StringUtil {
private static final String hexDigIts[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
"e", "f" };
public static String StringToMD5(String str) {
String result = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
result = byteArrayToHexString(md5.digest(str.getBytes()));
} catch (Exception e) {
}
return result;
}
public static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
public static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigIts[d1] + hexDigIts[d2];
}
}

View File

@ -0,0 +1,14 @@
mybatis:
type-aliases-package: com.example.demo.entity
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 123456
http:
encoding:
charset: utf-8
enabled: true

View File

@ -0,0 +1,16 @@
package com.example.demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootSpirngsecurityDemoApplicationTests {
@Test
public void contextLoads() {
}
}