當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
权限管理-整合SpringSecurity
生活随笔
收集整理的這篇文章主要介紹了
权限管理-整合SpringSecurity
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在spring_security引入相關依賴
<dependencies> <!-- Spring Security依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency> </dependencies>創建spring security核心配置類
Spring Security的核心配置就是繼承WebSecurityConfigurerAdapter并注解@EnableWebSecurity的配置。
這個配置指明了用戶名密碼的處理方式、請求路徑的開合、登錄登出控制等和安全相關的配置 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; 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;/*** <p>* Security配置類* </p>*/ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {private UserDetailsService userDetailsService;private TokenManager tokenManager;private DefaultPasswordEncoder defaultPasswordEncoder;private RedisTemplate redisTemplate;@Autowiredpublic TokenWebSecurityConfig(UserDetailsService userDetailsService, DefaultPasswordEncoder defaultPasswordEncoder,TokenManager tokenManager, RedisTemplate redisTemplate) {this.userDetailsService = userDetailsService;this.defaultPasswordEncoder = defaultPasswordEncoder;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}/*** 配置設置* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.exceptionHandling().authenticationEntryPoint(new UnauthorizedEntryPoint()).and().csrf().disable().authorizeRequests().anyRequest().authenticated().and().logout().logoutUrl("/admin/acl/index/logout").addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate)).and().addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate)).addFilter(new TokenAuthenticationFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();}/*** 密碼處理* @param auth* @throws Exception*/@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(defaultPasswordEncoder);}/*** 配置哪些請求不攔截* @param web* @throws Exception*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/api/**","/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");} }創建認證授權相關的工具類
DefaultPasswordEncoder:密碼處理的方法 import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component;/*** <p>* 密碼的處理方法類型* </p>*/ @Component public class DefaultPasswordEncoder implements PasswordEncoder {public DefaultPasswordEncoder() {this(-1);}/*** @param strength* the log rounds to use, between 4 and 31*/public DefaultPasswordEncoder(int strength) {}public String encode(CharSequence rawPassword) {return MD5.encrypt(rawPassword.toString());}public boolean matches(CharSequence rawPassword, String encodedPassword) {return encodedPassword.equals(MD5.encrypt(rawPassword.toString()));} } TokenManager:token操作的工具類 import io.jsonwebtoken.CompressionCodecs; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component;import java.util.Date;/*** <p>* token管理* </p>*/ @Component public class TokenManager {private long tokenExpiration = 24*60*60*1000;private String tokenSignKey = "123456";public String createToken(String username) {String token = Jwts.builder().setSubject(username).setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}public String getUserFromToken(String token) {String user = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getSubject();return user;}public void removeToken(String token) {//jwttoken無需刪除,客戶端扔掉即可。} } TokenLogoutHandler:退出實現 import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutHandler;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** <p>* 登出業務邏輯類* </p>*/ public class TokenLogoutHandler implements LogoutHandler {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenLogoutHandler(TokenManager tokenManager, RedisTemplate redisTemplate) {this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {String token = request.getHeader("token");if (token != null) {tokenManager.removeToken(token);//清空當前用戶緩存中的權限數據String userName = tokenManager.getUserFromToken(token);redisTemplate.delete(userName);}ResponseUtil.out(response, R.ok());} } UnauthorizedEntryPoint:未授權統一處理 import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /*** <p>* 未授權的統一處理方式* </p>*/ public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response,AuthenticationException authException) throws IOException, ServletException {ResponseUtil.out(response, R.error());} }創建認證授權實體類
import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.util.StringUtils;import java.util.ArrayList; import java.util.Collection; import java.util.List;/*** <p>* 安全認證用戶詳情信息* </p>*/ @Data @Slf4j public class SecurityUser implements UserDetails {//當前登錄用戶private transient User currentUserInfo;//當前權限private List<String> permissionValueList;public SecurityUser() {}public SecurityUser(User user) {if (user != null) {this.currentUserInfo = user;}}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {Collection<GrantedAuthority> authorities = new ArrayList<>();for(String permissionValue : permissionValueList) {if(StringUtils.isEmpty(permissionValue)) continue;SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);authorities.add(authority);}return authorities;}@Overridepublic String getPassword() {return currentUserInfo.getPassword();}@Overridepublic String getUsername() {return currentUserInfo.getUsername();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;} } import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable;/*** <p>* 用戶實體類* </p>*/ @Data @ApiModel(description = "用戶實體類") public class User implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "微信openid")private String username;@ApiModelProperty(value = "密碼")private String password;@ApiModelProperty(value = "昵稱")private String nickName;@ApiModelProperty(value = "用戶頭像")private String salt;@ApiModelProperty(value = "用戶簽名")private String token; }創建認證和授權的filter
TokenLoginFilter:認證的filter
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList;/*** <p>* 登錄過濾器,繼承UsernamePasswordAuthenticationFilter,對用戶名密碼進行登錄校驗* </p>*/ public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {private AuthenticationManager authenticationManager;private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate) {this.authenticationManager = authenticationManager;this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;this.setPostOnly(false);this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));}@Overridepublic Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)throws AuthenticationException {try {User user = new ObjectMapper().readValue(req.getInputStream(), User.class);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>()));} catch (IOException e) {throw new RuntimeException(e);}}/*** 登錄成功* @param req* @param res* @param chain* @param auth* @throws IOException* @throws ServletException*/@Overrideprotected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,Authentication auth) throws IOException, ServletException {SecurityUser user = (SecurityUser) auth.getPrincipal();String token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());redisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(), user.getPermissionValueList());ResponseUtil.out(res, R.ok().data("token", token));}/*** 登錄失敗* @param request* @param response* @param e* @throws IOException* @throws ServletException*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,AuthenticationException e) throws IOException, ServletException {ResponseUtil.out(response, R.error());} } TokenAuthenticationFilter:授權filter
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.util.StringUtils;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List;/*** <p>* 訪問過濾器* </p>*/ public class TokenAuthenticationFilter extends BasicAuthenticationFilter {private TokenManager tokenManager;private RedisTemplate redisTemplate;public TokenAuthenticationFilter(AuthenticationManager authManager, TokenManager tokenManager,RedisTemplate redisTemplate) {super(authManager);this.tokenManager = tokenManager;this.redisTemplate = redisTemplate;}@Overrideprotected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)throws IOException, ServletException {logger.info("================="+req.getRequestURI());if(req.getRequestURI().indexOf("admin") == -1) {chain.doFilter(req, res);return;}UsernamePasswordAuthenticationToken authentication = null;try {authentication = getAuthentication(req);} catch (Exception e) {ResponseUtil.out(res, R.error());}if (authentication != null) {SecurityContextHolder.getContext().setAuthentication(authentication);} else {ResponseUtil.out(res, R.error());}chain.doFilter(req, res);}private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {// token置于header里String token = request.getHeader("token");if (token != null && !"".equals(token.trim())) {String userName = tokenManager.getUserFromToken(token);List<String> permissionValueList = (List<String>) redisTemplate.opsForValue().get(userName);Collection<GrantedAuthority> authorities = new ArrayList<>();for(String permissionValue : permissionValueList) {if(StringUtils.isEmpty(permissionValue)) continue;SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);authorities.add(authority);}if (!StringUtils.isEmpty(userName)) {return new UsernamePasswordAuthenticationToken(userName, token, authorities);}return null;}return null;} }?
總結
以上是生活随笔為你收集整理的权限管理-整合SpringSecurity的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 权限管理-SpringSecurity介
- 下一篇: Nacos配置中心介绍