日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Security 初体验

發(fā)布時間:2024/3/24 javascript 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Security 初体验 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Spring Security 初體驗

①認證過濾器(登錄)
用于接收前端用戶登錄信息(username和password)與數(shù)據(jù)庫用戶信息(通過UserDetailsService查詢)就行判斷。
UserDetailsService:查詢存在用戶信息返回SecurityUser對象,否則拋出異常。
JWTPasswordHandler:判斷密碼是否正確。

/*** @author XS* @Version v1.0* @ClassName: 認證過濾器* @Description:* @Date: 2022/2/1 18:44*/ @Slf4j public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {private final AuthenticationManager authenticationManager;private RedisTemplate redisTemplate;public JWTAuthenticationFilter(AuthenticationManager authenticationManager, RedisTemplate redisTemplate) {this.authenticationManager = authenticationManager;this.redisTemplate = redisTemplate;this.setPostOnly(false);//設(shè)置登錄url和請求方式this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/member/rbac/login", "POST"));}/*** @description: 接收認證信息* @author: XS* @date: 2022/2/13*/@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {try {//前端用戶登錄信息User user = new ObjectMapper().readValue(request.getInputStream(), User.class);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));} catch (IOException e) {throw new RuntimeException(e);}}/*** @description: 登錄成功* @author: XS* @date: 2022/2/10*/@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {//獲取安全框架用戶(UserDetailsServiceImpl查到的)SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();//生成tokenString token = JWTTokenHandler.createToken(securityUser.getCurrentUserInfo().getId(), securityUser.getCurrentUserInfo().getUsername(), securityUser.getPermissionValueList());log.info("login success,Token:" + token);//返回結(jié)果給前端HashMap<String, String> login = new HashMap<>();login.put("token", token);Result<HashMap<String, String>> ok = Result.OK(login);response.setContentType("text/html;charset=utf-8");response.getWriter().write(new ObjectMapper().writeValueAsString(ok));//存入redisredisTemplate.opsForValue().set(securityUser.getCurrentUserInfo().getUsername(), token);}/*** @description: 登錄失敗* @author: XS* @date: 2022/2/10*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {log.info("login failure,Error:" + failed.toString());Result<Object> error = Result.error("登錄失敗");response.setContentType("text/html;charset=utf-8");response.getWriter().write(new ObjectMapper().writeValueAsString(error));} }

②授權(quán)過濾器(分配角色)
每次請求,判斷是否帶有token,如果存在則根據(jù)token得到用戶角色,并在全局安全框架上下文設(shè)置用戶角色。不存在則直接進入過濾(沒角色)。

/*** @author XS* @Version v1.0* @ClassName: 授權(quán)過濾器* @Description:* @Date: 2022/2/1 18:44*/ public class JWTAuthorizationFilter extends BasicAuthenticationFilter {public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {super(authenticationManager);}@Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException {logger.info("request uri:" + request.getRequestURI());String token = request.getHeader(SecurityConstants.TOKEN_HEADER);// 如果請求頭中沒有Authorization信息則直接放行了if (StringUtils.isEmpty(token)) {logger.warn("X-Token: not exist!");SecurityContextHolder.clearContext();chain.doFilter(request, response);return;}logger.info("X-Token:" + token);// 如果請求頭中有token,則進行解析,并且設(shè)置授權(quán)信息(設(shè)置角色)//請求頭中有 token 并且 token 的格式正確,則進行解析并判斷 token 的有效性,然后會在 Spring Security 全局設(shè)置授權(quán)信息SecurityContextHolder.getContext().setAuthentication(getAuthentication(token));System.out.println(SecurityContextHolder.getContext());super.doFilterInternal(request, response, chain);}private UsernamePasswordAuthenticationToken getAuthentication(String token) {try {// 通過 token 獲取用戶具有的角色String username = JWTTokenHandler.getUsernameByToken(token);List<String> roles = JWTTokenHandler.getRolesByToken(token);//封裝List<SimpleGrantedAuthority>if (Objects.requireNonNull(roles).size() > 0) {List<SimpleGrantedAuthority> authorities = roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());return new UsernamePasswordAuthenticationToken(username, token, authorities);}} catch (ExpiredJwtException exception) {logger.error("Request to parse JWT with invalid signature . Detail : " + exception.getMessage());}return null;} }

③實體類
SecurityUser:安全框架實體類
User:前端用戶登錄信息類

/*** @author XS* @Version v1.0* @ClassName: SecurityUser* @Description:* @Date: 2022/2/1 16:13*/ @Data @Slf4j public class SecurityUser implements UserDetails {//當前登錄用戶private transient User currentUserInfo;//當前權(quán)限private List<String> permissionValueList;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}@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;} } /*** @description: 前端用戶登錄信息* @author: XS* @date: 2022/2/17*/ @Data @ApiModel(description = "用戶實體類") public class User implements Serializable {private String id;private String username; // 不要改屬性名private String password; // 不要改屬性名private String salt;private String token; }

④處理類
JWTLogoutHandler:登出處理類(登出成功后處理)
JWTPasswordHandler:密碼處理類(密碼加密和密碼比較)
JWTTokenHandler:token處理類(生成token和通過token獲取用戶信息)

/*** @author XS* @Version v1.0* @ClassName: LogoutHandler* @Description:* @Date: 2022/2/1 16:07*/ @Slf4j public class JWTLogoutHandler implements LogoutSuccessHandler {private RedisTemplate redisTemplate;public JWTLogoutHandler(RedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {String token = request.getHeader(SecurityConstants.TOKEN_HEADER);if (token != null) {//清空當前用戶緩存中的權(quán)限數(shù)據(jù)String username = JWTTokenHandler.getUsernameByToken(token);redisTemplate.delete(username);}log.info("logout success");Result<String> logout = Result.OK("logout success");response.setContentType("text/html;charset=utf-8");try {response.getWriter().write(new ObjectMapper().writeValueAsString(logout));} catch (IOException e) {e.printStackTrace();}} } /*** @author XS* @Version v1.0* @ClassName: PasswordHandler* @Description:* @Date: 2022/2/1 15:31*/ @Slf4j public class JWTPasswordHandler implements PasswordEncoder {@Overridepublic String encode(CharSequence originalPassword) { // 密碼加密return SecureUtil.md5(originalPassword.toString());}@Overridepublic boolean matches(CharSequence originalPassword, String encodedPassword) { // 密碼加密比較return originalPassword.equals(encodedPassword);//return SecureUtil.md5(originalPassword.toString()).equals(encodedPassword); //加密后比較目前沒加密} } /*** @author ASUS* @Version v1.0* @ClassName: JWTTokenHandler* @Description:* @Date: 2022/2/1 16:00*/ public class JWTTokenHandler {public static String createToken(String id, String username, List<String> roles) {String JwtToken = Jwts.builder().setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256").setSubject("zqy-user").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRE)).claim("id", id).claim("username", username).claim("roles", roles).signWith(SignatureAlgorithm.HS256, SecurityConstants.JWT_SECRET_KEY).compact();return JwtToken;}/*** 根據(jù)token獲取用戶Username** @param token* @return*/public static String getUsernameByToken(String token) {if (StringUtils.isEmpty(token)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SecurityConstants.JWT_SECRET_KEY).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String) claims.get("username");}/*** 根據(jù)token獲取用戶id** @param jwtToken* @return*/public static String getUserIdByToken(String jwtToken) {if (StringUtils.isEmpty(jwtToken)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SecurityConstants.JWT_SECRET_KEY).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (String) claims.get("id");}/*** 根據(jù)token獲取用戶roles** @param jwtToken* @return*/public static List<String> getRolesByToken(String jwtToken) {if (StringUtils.isEmpty(jwtToken)) return null;Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SecurityConstants.JWT_SECRET_KEY).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (List<String>) claims.get("roles");} }

⑤認證詳情服務(wù)類(數(shù)據(jù)庫查詢用戶信息)

/*** @description: 認證詳情(數(shù)據(jù)庫查詢)* @author: XS* @date: 2022/2/17*/ @Service public class UserDetailsServiceImpl implements UserDetailsService {@Resourceprivate SysUserService sysUserService;@Resourceprivate SysRoleService sysRoleService;@Resourceprivate UserRoleService userRoleService;/**** 根據(jù)賬號獲取用戶信息* @param username:* @return: org.springframework.security.core.userdetails.UserDetails*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 從數(shù)據(jù)庫中取出用戶信息SysUser sysUser = sysUserService.selectByUsername(username);// 判斷用戶是否存在if (sysUser == null) {throw new UsernameNotFoundException("用戶不存在!");}// 當前用戶User curUser = new User();BeanUtils.copyProperties(sysUser, curUser);//查詢用戶角色List<UserRole> userRoleList = userRoleService.getUserRoleByUserId(curUser.getId());List<String> roleIdList = userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList());List<SysRole> sysRoles = sysRoleService.listByIds(roleIdList);List<String> authorities = sysRoles.stream().map(sysRole -> "ROLE_" + sysRole.getRoleCode()).collect(Collectors.toList());SecurityUser securityUser = new SecurityUser();//設(shè)置當前用戶securityUser.setCurrentUserInfo(curUser);//設(shè)置當前權(quán)限(角色)securityUser.setPermissionValueList(authorities);return securityUser;} }

⑥常量類

/*** @author XS* @description Spring Security相關(guān)配置常量*/ public final class SecurityConstants {/*** @description: token過期時間* @author: XS* @date: 2022/2/13*/public static final long EXPIRE = 1000 * 60 * 60 * 24; //存在時間/*** rememberMe 為 false 的時候過期時間是1個小時*/public static final long EXPIRATION = 60 * 60L;/*** rememberMe 為 true 的時候過期時間是7天*/public static final long EXPIRATION_REMEMBER = 60 * 60 * 24 * 7L;/*** JWT簽名密鑰硬編碼到應用程序代碼中,應該存放在環(huán)境變量或.properties文件中。*/public static final String JWT_SECRET_KEY = "C*F-JaNdRgUkXn2r5u8x/A?D(G+KbPeShVmYq3s6v9y$B&E)H@McQfTjWnZr4u7w";// 前端token頭public static final String TOKEN_HEADER = "X-Token";// 資源白名單public static final String[] RESOURCE_WHITELIST = {"/swagger-ui.html","/swagger-ui/*","/swagger-resources/**","/v2/api-docs","/v3/api-docs","/webjars/**",//knife4j"/doc.html",};public static final String H2_CONSOLE = "/h2-console/**";// 認證白名單(不用登錄也能訪問的接口)public static final String[] AUTHENTICATION_WHITELIST = {"/member/rbac/login","/member/rbac/logout","/member/rbac/register",};//授權(quán)白名單(沒有權(quán)限也能訪問的接口)public static final String[] AUTHORIZATION_WHITELIST = {//TODO};private SecurityConstants() {}}

⑦核心配置類(將上面自定義的類進行配置)

/*** @author XS* @Version v1.0* @ClassName: Web安全框架配件類* @Description:* @Date: 2022/2/1 15:28*/ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Slf4j public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Resourceprivate UserDetailsService userDetailsService;@Resourceprivate RedisTemplate redisTemplate;/*** @description: 核心配置* @author: XS* @date: 2022/2/14*/@Overrideprotected void configure(HttpSecurity http) throws Exception {log.info("spring-security started successfully!");//todo remember mehttp.csrf().disable()//關(guān)閉csrf.authorizeRequests()// 認證白名單(不用認證,不用登錄).antMatchers(SecurityConstants.AUTHENTICATION_WHITELIST).anonymous()// 授權(quán)白名單(無權(quán)限請求).antMatchers(SecurityConstants.AUTHORIZATION_WHITELIST).permitAll()// 權(quán)限請求.anyRequest().authenticated().and()// 登出路徑.logout().logoutUrl("/member/rbac/logout")// 登出成功處理器.logoutSuccessHandler(new JWTLogoutHandler(redisTemplate)).and()// 認證過濾器.addFilter(new JWTAuthenticationFilter(authenticationManager(), redisTemplate))// 授權(quán)過濾器.addFilter(new JWTAuthorizationFilter(authenticationManager()))// 不需要session(不創(chuàng)建會話).sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 異常處理.exceptionHandling()// 授權(quán)異常.authenticationEntryPoint(new JWTAuthenticationEntryPoint())// 請求拒絕.accessDeniedHandler(new JWTAccessDeniedHandler());}/*** 密碼處理** @param auth* @throws Exception*/@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(new JWTPasswordHandler());}/*** 配置哪些請求不攔截*/@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers(SecurityConstants.RESOURCE_WHITELIST);} }

總結(jié)

以上是生活随笔為你收集整理的Spring Security 初体验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 不卡中文字幕 | 色婷婷国产精品 | 亚洲一区在线看 | 黄色私人影院 | 男女做那个的全过程 | 97免费公开视频 | 浪荡奴双性跪着伺候 | 韩国伦理在线看 | 无码h黄肉3d动漫在线观看 | 国产精品免费一区二区三区都可以 | 亚洲伦理一区 | 国产成人精品aa毛片 | 女人和拘做爰正片视频 | 91入囗 | 国产精品69毛片高清亚洲 | 日韩一区免费 | 亚洲一区二区三区视频 | 在线免费观看一区 | 中国新婚夫妻性猛交 | 国产一区二区福利 | 天天爽一爽 | 免费看污黄网站在线观看 | 久久精品视频18 | 国产伦理久久精品久久久久 | a级无毛片 | 亚洲va久久久噜噜噜无码久久 | 久久亚洲精华国产精华液 | 久久久久亚洲av无码麻豆 | 少妇真实被内射视频三四区 | 国产麻豆一精品一av一免费 | 欧美一卡二卡在线观看 | 日本一区二区三区免费观看 | 欧美高清一区二区三区四区 | 亚洲精品一区二区三区四区 | 黄色大片一级片 | 中文字幕三级 | 亚洲黄色精品视频 | 九色视频偷拍少妇的秘密 | 亚洲老老头同性老头交j | 亚洲少妇网 | wwwxxx日韩 | 欧美三级网 | 中文字幕免费在线视频 | 美女张开腿露出尿口 | 玖玖视频 | 欧美大片在线播放 | 九九热在线观看 | 日韩成人精品一区 | 国产妇女视频 | 麻豆视频网站入口 | 亚洲一区在线免费观看 | 国产亚洲成av人在线观看导航 | 日本在线三级 | 黄网站色视频 | 亚州男人的天堂 | 草久影院 | 超碰超在线 | av一区三区 | 日本a在线播放 | 色综合99久久久无码国产精品 | 国产精品夜色一区二区三区 | 日韩欧美在线观看一区二区 | 欧美在线免费观看视频 | 欧美丰满一区二区免费视频 | 久久久久久国产视频 | 无码h黄肉3d动漫在线观看 | 97av超碰| 性www| 国产极品尤物 | 亚洲码无人客一区二区三区 | 99免费视频 | 日日噜噜噜噜人人爽亚洲精品 | 九色精品视频 | 日日做夜夜爽毛片麻豆 | 人妻丰满熟妇aⅴ无码 | 国产老头老太作爱视频 | 超碰97干| 亚洲成av人片一区二区梦乃 | 91视频观看 | 亚洲国内在线 | 中文字幕一区二区在线观看视频 | a久久久久 | 欧美精品乱码 | 香蕉视频一级片 | 色婷婷av一区二区三区四区 | 91官网在线 | 91这里只有精品 | 波多野结衣中文字幕一区 | 亚洲国产精品激情在线观看 | 视频一区二区在线播放 | 91官网视频 | 丁香花高清在线 | 狠狠搞狠狠干 | 大战熟女丰满人妻av | 色01看片网 | 亚洲 欧美 日韩 国产综合 在线 | 欧美肉大捧一进一出免费视频 | 国产精品羞羞答答在线观看 | 午夜a级片 |