Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to integrate Spring Security JWT in Springboot to realize Interface Authority Authentication

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Editor to share with you how to integrate Spring Security JWT in Springboot to achieve interface authority authentication, I believe most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!

1. Add dependency org.springframework.boot spring-boot-starter-security io.jsonwebtoken jjwt 0.9.12, integrate JWT tool class (JwtUtils) package com.dreamteam.chdapp.utils;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;import java.util.Date;import java.util.HashMap;import java.util.Map / * * @ Author HeYunHui * @ create, 2020-11-15 14:12 * / public class JwtUtils {private static final Logger logger= LoggerFactory.getLogger (JwtUtils.class); public static final long EXPIRATION_TIME=60*60*1000;// token Ring validity period public static final String SECRET= "abc123456def"; / / token Ring key public static final String TOKEN_PREFIX= "Bearer"; / / token Ring header ID public static final String HEADER_STRING= "Passport" / / configure the key value of token ring in http heads public static final String ROLE= "ROLE"; / / Custom field-role field / / generate token ring public static String generateToken (String userRole,String userid) {HashMap map=new HashMap (); map.put (ROLE,userRole); map.put ("userid", userid) String jwt= Jwts.builder () .setClaims (map) .setExpiration (new Date (System.currentTimeMillis () + EXPIRATION_TIME)) .signWith (SignatureAlgorithm.HS512,SECRET) .compact (); return TOKEN_PREFIX+ "" + jwt;} / / generate token ring public static String generateToken (String userRole,String userid,long exprationtime) {HashMap map=new HashMap () Map.put (ROLE,userRole); map.put ("userid", userid); String jwt= Jwts.builder () .setClaims (map) .setExpiration (new Date (System.currentTimeMillis () + exprationtime)) .signWith (SignatureAlgorithm.HS512,SECRET) .compact (); return TOKEN_PREFIX+ "" + jwt } / / token Ring check public static Map validateTokenAndGetClaims (HttpServletRequest request) {String token=request.getHeader (HEADER_STRING); if (token==null) {throw new TokenValidationException ("Missing Token") } else {Map body= Jwts.parser () .setSigningKey (SECRET) .parseClaimsJws (token.replace (TOKEN_PREFIX, ")) .getBody (); return body;}} static class TokenValidationException extends RuntimeException {public TokenValidationException (String msg) {super (msg) 3. Integrated JWT filter (interceptor / filter) package com.dreamteam.chdapp.filter;import com.dreamteam.chdapp.utils.JwtUtils;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.util.AntPathMatcher;import org.springframework.util.PathMatcher;import org.springframework.web.filter.OncePerRequestFilter;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.Arrays;import java.util.Map;import static com.dreamteam.chdapp.utils.JwtUtils.ROLE;/** * @ Author HeYunHui * @ create 14:46 on 2020-11-15 * / public class JwtAuthenticationFilter extends OncePerRequestFilter {private static final PathMatcher pathmatcher = new AntPathMatcher (); private String [] protectUrlPattern = {"/ manage/**", "/ member/**", "/ auth/**"} / / which requests require security verification public JwtAuthenticationFilter () {} @ Override protected void doFilterInternal (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {/ / can you log in here in multiple ways? try {if (isProtectedUrl (httpServletRequest)) {Map claims = JwtUtils.validateTokenAndGetClaims (httpServletRequest); String role = String.valueOf (claims.get (ROLE)) String userid = String.valueOf (claims.get ("userid")); / / this is where we directly inject SecurityContextHolder.getContext () .setAuthentication (new UsernamePasswordAuthenticationToken (userid, null, Arrays.asList (()-> role). } catch (Exception e) {e.printStackTrace (); httpServletResponse.sendError (HttpServletResponse.SC_UNAUTHORIZED, e.getMessage ()); return;} filterChain.doFilter (httpServletRequest, httpServletResponse);} / / whether it is a protected connection private boolean isProtectedUrl (HttpServletRequest request) {boolean flag = false; for (int I = 0; I)

< protectUrlPattern.length; i++) { if (pathmatcher.match(protectUrlPattern[i], request.getServletPath())) { return true; } } return false; }}4、配置JWT config类(配置类) 跨域访问:客户端与服务端域名不同或是端口号不同。防止跨域攻击 package edu.ynmd.cms.config;import edu.ynmd.cms.filter.JwtAuthenticationFilter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;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.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.crypto.password.PasswordEncoder;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import org.springframework.security.web.firewall.HttpFirewall;import org.springframework.security.web.firewall.StrictHttpFirewall;@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean public HttpFirewall allowUrlEncodedSlashHttpFirewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); firewall.setAllowUrlEncodedSlash(true); return firewall; } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .cors() //允许跨域访问 .and() .authorizeRequests() .antMatchers("/").authenticated() //配置那些url需要进行校验--所有请求都需要校验"/" .antMatchers("/public/**").permitAll() //那些请求不需要校验 .anyRequest().authenticated() //自定义校验类 .and() .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS)//关闭session ; }}5、Action注解 在Controller类中添加 @CrossOrigin@RestController@PreAuthorize("hasAuthority('admin')") //配置角色,拥有该角色的用户方可访问@RequestMapping("/manage") postman测试http://localhost:7070/manage/userList,不可访问 public开头的可以访问 6、token令牌环,访问需校验的资源 public的Controller类添加 @PostMapping("/login") @ResponseBody public HashMap login( @RequestBody Account account) throws IOException {// Users u=manageService.getUserByUserNameAndPass(account.username,account.password); if(account.username.equals("admin")&&account.password.equals("123456")){// if(u!=null){ String jwt= JwtUtils.generateToken("admin","123456789abc");// String jwt= JwtUtils.generateToken(u.getRoleid(),u.getUsersid()); return new HashMap(){{ put("msg","ok"); put("token",jwt);// put("role",u.getRoleid()); put("role","admin"); }}; } else { //return new ResponseEntity(HttpStatus.UNAUTHORIZED); return new HashMap(){{ put("msg","error"); put("token","error"); }}; } } public static class Account{ public String username; public String password; } postman测试,随便输用户名密码 输入代码中的用户名密码 去JWT官网https://jwt.io/,页面下滑,将得到的token输入,得到 manage的Controller类中添加测试 @GetMapping("testSecurityResource") @ResponseBody public String testSecurityResource() throws Exception{ return "受保护的资源"; } 用postman访问http://localhost:7070/manage/testSecurityResource,返回结果 7、service工具类 通用请求处理 package com.dreamteam.chdapp.controller.common;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;/** * 通用请求处理 * @Author HeYunHui * @create 2020/11/14 15:38 */@Controllerpublic class CommonController { protected static final Logger log= LoggerFactory.getLogger(CommonController.class); /** * 字符串为空 * @param value * @return */ public static boolean isNullOrSpace(String value){ if(value==null){ return true; } else { if(value.equals("")){ return true; } else { return false; } } }} Service层 String getCurrentUserId();//从令牌环中获取useridString getCurrentRole();//从令牌环中获取角色id ServiceImpl /** * 获取当前登录用的的Id * @return */ @Override public String getCurrentUserId() { String userid= (String) SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); if(CommonController.isNullOrSpace(userid)){ return null; } else { return userid; } } /** * 获取当前登录用户的角色 * @return */ @Override public String getCurrentRole() { String role=null; Collection authorities = (Collection) SecurityContextHolder.getContext().getAuthentication().getAuthorities(); for (GrantedAuthority authority : authorities) { role = authority.getAuthority(); } if(CommonController.isNullOrSpace(role)){ return null; } else{ return role; } } 修改manage的Controller类 @GetMapping("testSecurityResource") @ResponseBody public String testSecurityResource() throws Exception{ String userid=userInfoService.getCurrentUserId(); String role=userInfoService.getCurrentRole(); return "受保护的资源,当前用户的id是"+userid+"当前用户的角色是"+role; } 用postman测试 这是前面自定义的 8、识别token信息 如果将下图中的角色换掉,将不能访问 9、自动更新令牌环 添加Controller类 package com.dreamteam.chdapp.controller;import com.dreamteam.chdapp.controller.common.CommonController;import com.dreamteam.chdapp.utils.JwtUtils;import org.springframework.security.access.prepost.PreAuthorize;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;import java.util.Collection;import java.util.HashMap;/** * 令牌环自动更新 * @Author HeYunHui * @create 2020/11/16 17:24 * @PreAuthorize("hasAuthority('admin')")//只允许有admin角色的用户访问 hasAnyAuthority([auth2,auth3]) */@CrossOrigin@RestController@PreAuthorize("hasAnyAuthority('admin','member')")@RequestMapping("/auth")public class AuthController { /** * 更新令牌环信息 * @param request * @return */ @GetMapping("refreshToken") @ResponseBody public HashMap refreshToken(HttpServletRequest request){ String role=null; Collection authorities = (Collection) SecurityContextHolder.getContext().getAuthentication().getAuthorities(); for (GrantedAuthority authority : authorities) { role = authority.getAuthority(); } // UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); String userid= (String)SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); if(CommonController.isNullOrSpace(role)){ return new HashMap(){{ put("token","error"); }}; } else{ String jwt=""; //一小时 jwt= JwtUtils.generateToken(role,userid,60*60*1000); HashMap m=new HashMap(); m.put("token",jwt); return m; } } /** * 获取当前登录用户的角色 * @return */ @GetMapping("getRole") @ResponseBody public HashMap getRoleByToken(){ String role=""; String userid=""; Collection authorities = (Collection) SecurityContextHolder.getContext().getAuthentication().getAuthorities(); for (GrantedAuthority authority : authorities) { role = authority.getAuthority(); } if(CommonController.isNullOrSpace(role)){ return new HashMap(){{ put("role","error"); }}; } else{ HashMap m=new HashMap(); m.put("role",role); return m; } }} 用postman测试 10、使用数据库存储用户信息 (1)实体类 package com.dreamteam.chdapp.entity;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.stereotype.Component;@Component@Data@AllArgsConstructor@NoArgsConstructor/** * 表名 */@TableName("users")public class Users { @TableId(type = IdType.AUTO) private String usrId; private String usrName; private String usrTel; private String usrPwd; private String usrType; } UserMapper package com.dreamteam.chdapp.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.dreamteam.chdapp.entity.Users;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import org.springframework.stereotype.Repository;import java.util.List;/** * @Author HeYunHui * @create 2020/11/11 21:50 */@Repository@Mapperpublic interface UserMapper extends BaseMapper { List getUsersByUsrNameAndPwd(@Param("usrName")String usrName, @Param("usrPwd") String usrPwd);} UsersMapper.xml select * from users where #{usrName}=usr_name and #{usrPwd}=usr_pwd service Users getUsersByUsrNameAndPwd(String usrName,String usrPwd); serviceImpl JWT获取用户名密码 @Override public Users getUsersByUsrNameAndPwd(String usrName, String usrPwd) { List ul=userMapper.getUsersByUsrNameAndPwd(usrName,usrPwd); if(ul.size()>

0) {return ul.get (0);} return null;}

Controller

@ PostMapping ("/ login") @ ResponseBody public HashMap login (@ RequestBody Account account) throws IOException {Users u=userInfoService.getUsersByUsrNameAndPwd (account.username,account.password); / / if (account.username.equals ("admin") & & account.password.equals ("123456")) {if (upright null) {/ / String jwt= JwtUtils.generateToken ("admin", "123456789abc") String jwt= JwtUtils.generateToken (u.getUsrType (), u.getUsrId ()); return new HashMap () {{put ("msg", "ok"); put ("token", jwt); put ("role", u.getUsrType ()); / / put ("role", "admin");}} } else {/ / return new ResponseEntity (HttpStatus.UNAUTHORIZED); return new HashMap () {{put ("msg", "error"); put ("token", "error");}};}} public static class Account {public String username; public String password } these are all the contents of the article "how to integrate Spring Security JWT in Springboot to achieve interface authority authentication". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report