首页 > 其他分享 >springboot3项目的搭建四.3(security登录认证配置)

springboot3项目的搭建四.3(security登录认证配置)

时间:2024-06-12 16:55:46浏览次数:25  
标签:return String request 认证 static springboot3 new security public

security的jwt验证:

总体来说,我们加入依赖项,security就已经开始生效了,但是使用的默认的UserDetails和UserDetailsService,

一 、我们只要继承UserDetailsService,在数据库中查询用户和权限列表,封装成UserDetails的实现类,返回就可以实现,security验证的接管,最多在security配置类中,放行一些路径。

 

二 、如果自己想重新整个验证路径,那么在security配置类,暴露一个AuthenticationManager,然后自己写验证流程。如:

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    AuthenticationManager authenticationManager;

    //自定义的spring security登录流程
    @Override
    public Map<String, Object> login(String user_name, String password) throws Exception {
        //1.封装Authentication对象
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user_name,password);
        //2.进行校验 (会自动调用UserDetailsService.loadUserByUsername)
        Authentication authenticate =authenticationManager.authenticate(authentication);
        //3.如果校验为空,认证失败抛出异常
        if(Objects.isNull(authenticate)) {
            throw new RuntimeException("登录失败!");
        }
        //4.取出,存入的用户对象
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        //5.生产jwt字符串
        String loginUserStr = JSON.toJSONString(loginUser);
        //JwtUtils
        String jwt = JwtUtils.createJWT(loginUserStr, null);
        //System.out.println(jwt);
        //解析
        //Claims claims = JwtUtils.parseJWT(jwt);
        //System.out.println(claims);
        //System.out.println(claims.getSubject());
        Map<String,Object> loginObj = new HashMap<String,Object>();
        loginObj.put("admin",loginUser.getAdmins());
        loginObj.put("jwt",jwt);

        return loginObj;
    }
    

}

这个自定义验证流程,会自动找我们已经暴露出来的UserDetails和UserDetailsService。

最后我们再完善一下security的配置类,排除一些路径,添加一些验证成功和失败的处理器Handler,在如果需要其他一些验证过滤器(验证码,jwt),可以加到原有的过滤器链中。

 

 

============下来我们就按照自定义的验证,完善一下其周边的一些配置。

1、上面的自定义验证,也会自动调用UserDetailsService,随意我们也必须重写UserDetailsService和UserDetails.

UserDetailsService:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    AdminsService adminsService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //1.查询用户信息
        AdminsEntity admins = adminsService.getAdminByName(username);
        if(Objects.isNull(admins)){
            throw new RuntimeException("用户名错误!");
        }
        //2.查询用户权限列表
        //List<Permission> permissions = permissionDao.findByUserid(myUser.getUserid());
        //Collection<? extends GrantedAuthority> authorities=permissions.stream().map(item->new SimpleGrantedAuthority(item.getPerCode())).collect(Collectors.toList());
        //System.out.println(authorities);

        System.out.println(admins);
        LoginUser loginUser = new LoginUser(admins,admins.getId(),null);

        return loginUser;
    }
}

UserDetails:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements UserDetails {
    public AdminsEntity admins;
    public Integer user_id;
    @JsonIgnore
    public List<PermissionEntity> permissions;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if(permissions == null) return null;
        Collection<? extends GrantedAuthority> authorities=permissions.stream().map(item->new SimpleGrantedAuthority(item.getPerCode())).collect(Collectors.toList());
        return authorities;
    }

    @Override
    public String getPassword() {
        return admins.getPassWord();
    }

    @Override
    public String getUsername() {
        return admins.getUserName();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

 

2、其中最重要验证环节,要写的都写完了,周边的一些配置,(使用的密码加密类,登录成功和失败的处理器,加入jwt或验证码过滤器)

/**
 * spring security配置
 */
@Configuration
@AllArgsConstructor
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    /**
     * 自定义用户认证逻辑
     */
    @Autowired(required=true)
    public UserDetailsServiceImpl userDetailsServiceImpl;
    /**
     *  验证码验证逻辑过滤器
     */
    @Autowired(required=true)
    public ValidateCodeFilter validateCodeFilter;

    /**
     * 认证失败处理类(jwt)与web用其一
     */
    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;
    /**
     * 认证失败处理类(web)与jwt用其一
     */
    @Autowired
    private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    /**
     * 退出处理类
     */
    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    /**
     * token认证过滤器
     */
    @Autowired
    private JwtAuthenticationTokenFilter authenticationTokenFilter;

    /**
     * 跨域过滤器
     */
    @Autowired
    private CorsFilter corsFilter;

    /**
     * 允许匿名访问的地址
     */
    private final String[] paths = {
            "/druid/**", "/system/captcha/line",
            "/druid/login.html/**",
            "/system/login", "/js/**", "/*/*.json", "/*/*.yml",
            "/prims/**", "/type/**", "/system/file/**",
            "/diagram-viewer/**", "/images/**",
            "/api/login/**", "/api/file/**",
            "/css/**", "/*/*.ico", "/swagger-resources/**",
            "/swagger/**", "/swagger-ui/**",
            "/webjars/**", "/v3/**", "/v2/**", "/doc.html/**"
    };

    @Autowired
    private DataSource dataSource;


    /**
     * 获取AuthenticationManager(认证管理器),登录时认证使用
     * @return
     * @throws Exception
     */
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        DaoAuthenticationProvider provider =  new DaoAuthenticationProvider();
        provider.setPasswordEncoder(bCryptPasswordEncoder());
        provider.setUserDetailsService(userDetailsServiceImpl);
        return new ProviderManager(provider);
    }

    /**
     * 获取AuthenticationManager(认证管理器),登录时认证使用
     * @param authenticationConfiguration
     * @return
     * @throws Exception
     */
    //方式一 (新方式,默认AuthenticationManager使用的事暴露出来的UserDetailsService和PasswordEncoder)
//    @Bean
//    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
//        return authenticationConfiguration.getAuthenticationManager();
//    }

    //方法二:(旧方式,已经不继承父类)
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception
//    {
//        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
//    }

    /**
     * anyRequest          |   匹配所有请求路径
     * access              |   SpringEl表达式结果为true时可以访问
     * anonymous           |   匿名可以访问
     * denyAll             |   用户不能访问
     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
     * permitAll           |   用户可以任意访问
     * rememberMe          |   允许通过remember-me登录的用户访问
     * authenticated       |   用户登录后可访问
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 注解标记允许匿名访问的url
        //http.authorizeHttpRequests(conf -> conf.requestMatchers(paths).permitAll());

        //http.csrf(httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.disable());
        http
                // 基于 web,需要 csrf (其实不用配置,默认支持),基于jwt,需要禁用
                .csrf(AbstractHttpConfigurer::disable)
                // 基于 web,需要 session  (其实不用配置,默认支持),基于jwt,配置为SessionCreationPolicy.STATELESS
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))

                // 下面开始设置权限过滤请求
                .authorizeHttpRequests(authorize -> authorize
                        // 请求放开
                        // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                        .requestMatchers("/sys/login","/login?error=true2","/login?error=AuthenticationEntryPointImpl","/login?**","/dologin","/logout","/register", "/captchaImage","/test/*").permitAll()
                        // 静态资源,可匿名访问
                        .requestMatchers(HttpMethod.GET, "/", "/*.html", "/*/*.html", "/*/*.css", "/*/*.js", "/profile/**").permitAll()
                        .requestMatchers("/css/**","/js/**","/img/**","/uploads/*s*","*/favicon.ico","/favicon.ico").permitAll()
                        .requestMatchers("/swagger-ui.html", "/swagger-resources/*", "/webjars/*", "/*/api-docs", "/druid/*").permitAll()
                        // 其他地址的访问均需验证权限
                        .anyRequest().authenticated()
                );

        //请求过滤规则

        //指定登录表单的规则 (新版配置用lambda表达式, 只做记录,用于web验证)
        //http.formLogin(fl->fl//这个路径必须和登录表单的提交路径一致。
                //.loginProcessingUrl("/dologin")
                //设置自定义登录界面
                //.loginPage("/login")
                //登录成功后转发的路径
                //.successForwardUrl("/main")

                //登录失败跳转地址 (做记录)
                //.failureForwardUrl("/login?error=true")
                //.failureUrl("/login?error=true")
                //.failureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error=loginFailure"))
                //.failureHandler(new AuthenticationEntryPointFailureHandler(customAuthenticationEntryPoint))
                //.failureHandler(customAuthenticationFailureHandler)
                //.permitAll());

        //登出配置(web)
        http.logout(lt->lt.logoutUrl("/logout").logoutSuccessUrl("/").clearAuthentication(true));

        //记住我功能
        //https://blog.csdn.net/weixin_47826286/article/details/127799842

//        http.rememberMe(re->re.tokenRepository(persistentTokenRepository())
//                // 有效时间:单位s
//                .tokenValiditySeconds(60)
//                .userDetailsService(userDetailsServiceImpl));



        //认证失败处理器 (之前版本配置)
        //http.exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint);//web形式用customAuthenticationEntryPoint,jwt形式用unauthorizedHandler

        //认证失败处理器 (7.0新版本配置,用lambda表达式)
        //authenticationEntryPoint认证失败的处理逻辑,accessDeniedHandler访问拒绝的处理逻辑
        http.exceptionHandling(
                exceptions -> exceptions.authenticationEntryPoint(unauthorizedHandler)
                        .accessDeniedHandler(new MyAccessDeniedHandler())
        );



        // 配置登录之前添加一个验证码的过滤器
        http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
        // jwt 校验
        http.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }


    /**
     * 强散列哈希加密实现
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder()
    {
        return new BCryptPasswordEncoder();
    }


    /**
     * 记住我功能的数据库配置(在配置项中rememberMe最好配置token过期时间)
     * @return
     */
    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // 如果token表不存在,使用下面语句可以初始化该表;若存在,请注释掉这条语句,否则会报错。
        //tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }


    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        //return (web) -> web.ignoring().antMatchers("/css/**","/js/**","/img/**","/uploads/**","**/favicon.ico"); //之前配置
        return (web) -> web.ignoring().requestMatchers("/css/**","/js/**","/img/**","/uploads/**","*/favicon.ico"); //新配置

    }


    /**
     * 配置跨源访问(CORS)
     * @return
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
        return source;
    }


}

3、下列是配置类中设置的,验证成功或失败处理器,和过滤器.

 JwtAuthenticationTokenFilter: 

/**
 * token过滤器 验证token有效性
 *
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
//    @Autowired
//    private TokenService tokenService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {
//        LoginUser loginUser = tokenService.getLoginUser(request);
//        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
//        {
//            tokenService.verifyToken(loginUser);
//            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
//            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//        }

        //1.放行某些地址(入登录地址)
        String uri = request.getRequestURI();
        if(uri.equals("/sys/login") || uri.equals("/sys/verify")){
            chain.doFilter(request, response);
            return;
        }
        //2.接受参数
        String token = request.getHeader("Authorization");
        //System.out.println(token);
        if(!StringUtils.hasText(token)){
            throw new RuntimeException("token为空!");
        }
        //3.验证非空
        LoginUser loginUser = null;
        //4.解析校验参数
        try {
            Claims claims = JwtUtils.parseJWT(token);
            //System.out.println(claims);
            //System.out.println(claims.getSubject());
            String loginUserStr = claims.getSubject();
            //System.out.println(loginUserStr);
            loginUser = JSON.parseObject(loginUserStr,LoginUser.class);
        } catch (Exception e) {
            throw new RuntimeException("token校验失败");
        }

        //5.把验证完的userDetails 再次防暑spring Security上下文中
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser,null,null);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //6.放行过滤器连
        chain.doFilter(request, response);
    }
}
ValidateCodeFilter:这个和生成验证码配套使用(web验证码存在sessiion,jwt形式验证码存redis等)
这里演示的验证码在生成时存在session中.
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //得到请求地址
        String requestURI = request.getRequestURI();
        System.out.println("requestURL:" + requestURI+" Method:"+request.getMethod());


        // 非登录请求不校验验证码,直接放行
        if ( ("/dologin".equals(request.getRequestURI()) && request.getMethod().equalsIgnoreCase("POST") )) {
            try {
                //校验验证码
                verificationCode(request);
                //验证码校验通过后,对请求进行放行
                filterChain.doFilter(request, response);
            } catch (AuthenticationException exception) {
                new CustomAuthenticationFailureHandler().onAuthenticationFailure(request, response, exception);
                return;
            }
        }else{
            filterChain.doFilter(request, response);
        }

    }
    public void verificationCode (HttpServletRequest httpServletRequest) throws AuthenticationException {
        HttpSession session = httpServletRequest.getSession();
        String savedCode = (String) session.getAttribute("captcha");
        if (!StringUtils.hasLength(savedCode)) {
            // 随手清除验证码,不管是失败还是成功,所以客户端应在登录失败时刷新验证码
            session.removeAttribute("captcha");
        }
        String requestCode = httpServletRequest.getParameter("captcha");
        // 校验不通过抛出异常
        if (!(StringUtils.hasLength(requestCode) && StringUtils.hasLength(savedCode) && requestCode.equals(savedCode))) {
            //throw new AuthenticationServiceException("验证码错误..");
            throw new VerificationCodeException("验证码错误..");
        }
    }



}

AuthenticationEntryPointImpl 

/**
 * 认证失败处理类(jwt) 返回未授权
 *
 */
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
{
    private static final long serialVersionUID = -8970718410437077606L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
            throws IOException
    {
        String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
        //ReturnCode rc = ReturnCode.NO_OPERATOR_AUTH;
        ServletUtils.renderString(response, JSON.toJSONString(ResultData.error(403,msg)));
    }
}

CustomAuthenticationEntryPoint 

/**
 * 认证失败处理类(web) 返回未授权
 *
 */
@Component
@Slf4j
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable
{
    private static final long serialVersionUID = -8970718410437077606L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {

        log.info("登录失败....11");
        //authException.printStackTrace();
        response.setContentType("text/html; charset=UTF-8");
        request.setAttribute("errorMsg", "登录失败");
        request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION,authException);
        request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, authException);

        response.sendRedirect("/login?error=AuthenticationEntryPointImpl");
        //request.getRequestDispatcher("/login?error=AuthenticationEntryPointImpl").forward(request, response);
    }
}

LogoutSuccessHandlerImpl 

/**
 * 自定义退出处理类 返回成功
 *
 * @author ruoyi
 */
@Configuration
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
{
    //要在配置文件配置
    //@Autowired
    //private TokenService tokenService;

    /**
     * 退出处理
     *
     * @return
     */
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException
    {
//        LoginUser loginUser = tokenService.getLoginUser(request);
//        if (StringUtils.isNotNull(loginUser))
//        {
//            String userName = loginUser.getUsername();
//            // 删除用户缓存记录
//            tokenService.delLoginUser(loginUser.getToken());
//            // 记录用户退出日志
//            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
//        }
//        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
    }
}
MyAccessDeniedHandler 无权限访问处理器:返回一些json或字符串
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(
            HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException
    ) throws IOException, ServletException {

//        ObjectMapper objectMapper = new ObjectMapper();
//        CommonResult commonResult = new CommonResult();
//        commonResult.setCode(YIXGResultEnum.NO_PERMISSION.getCode())
//                .setMessage(YIXGResultEnum.NO_PERMISSION.getMessage());
//        response.setContentType("application/json;charset=UTF-8");
//        response.getWriter().write(objectMapper.writeValueAsString(commonResult));
//        response.getWriter().flush();
//        response.getWriter().close();
    }
}


4、用到的一些额外工具类,jwt工具类,字符串工具类,servlet等工具类。

JwtUtils :

/**
 * JWT工具类
 */
public class JwtUtils {

    //有效期为
    public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000  一个小时
    //设置秘钥明文
    public static final String JWT_KEY = "sangeng";

    public static String getUUID(){
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        return token;
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @return
     */
    public static String createJWT(String subject) {
        JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @param ttlMillis token超时时间
     * @return
     */
    public static String createJWT(String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
        return builder.compact();
    }

    private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        SecretKey secretKey = generalKey();
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        if(ttlMillis==null){
            ttlMillis=JwtUtils.JWT_TTL;
        }
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("sg")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);
    }

    /**
     * 创建token
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间
        return builder.compact();
    }

    public static void main(String[] args) throws Exception {
        String jwt = createJWT("123");
        System.out.println(jwt);
        Claims claims1 = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI0NjBmYjNlZjkyZmU0OGU5YWI0YjlkNWE4ZjBmZmQ1OSIsInN1YiI6IjIiLCJpc3MiOiJzZyIsImlhdCI6MTY3NzU3MTIzNywiZXhwIjoxNjc3NTc0ODM3fQ.Tbt70u_ZSGECVIVUv2MhtdV2WnhR_Dxy47AlNWKBj4k");
        System.out.println(claims1.getSubject());
        // String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjYWM2ZDVhZi1mNjVlLTQ0MDAtYjcxMi0zYWEwOGIyOTIwYjQiLCJzdWIiOiJzZyIsImlzcyI6InNnIiwiaWF0IjoxNjM4MTA2NzEyLCJleHAiOjE2MzgxMTAzMTJ9.JVsSbkP94wuczb4QryQbAke3ysBDIL5ou8fWsbt_ebg";
        //Claims claims = parseJWT(token);
        //System.out.println(claims);
    }

    /**
     * 生成加密后的秘钥 secretKey
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtils.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 解析
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }


}

ServletUtils: 具体一些工具类 可以参照 ruoyi框架中的

/**
 * 客户端工具类
 *
 * @author ruoyi
 */
public class ServletUtils
{
    /**
     * 获取String参数
     */
    public static String getParameter(String name)
    {
        return getRequest().getParameter(name);
    }

    /**
     * 获取String参数
     */
    public static String getParameter(String name, String defaultValue)
    {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name)
    {
        return Convert.toInt(getRequest().getParameter(name));
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name, Integer defaultValue)
    {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取Boolean参数
     */
    public static Boolean getParameterToBool(String name)
    {
        return Convert.toBool(getRequest().getParameter(name));
    }

    /**
     * 获取Boolean参数
     */
    public static Boolean getParameterToBool(String name, Boolean defaultValue)
    {
        return Convert.toBool(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获得所有请求参数
     *
     * @param request 请求对象{@link ServletRequest}
     * @return Map
     */
    public static Map<String, String[]> getParams(ServletRequest request)
    {
        final Map<String, String[]> map = request.getParameterMap();
        return Collections.unmodifiableMap(map);
    }

    /**
     * 获得所有请求参数
     *
     * @param request 请求对象{@link ServletRequest}
     * @return Map
     */
    public static Map<String, String> getParamMap(ServletRequest request)
    {
        Map<String, String> params = new HashMap<>();
        for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
        {
            params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
        }
        return params;
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest()
    {
        return getRequestAttributes().getRequest();
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse()
    {
        return getRequestAttributes().getResponse();
    }

    /**
     * 获取session
     */
    public static HttpSession getSession()
    {
        return getRequest().getSession();
    }

    public static ServletRequestAttributes getRequestAttributes()
    {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     * @param string 待渲染的字符串
     */
    public static void renderString(HttpServletResponse response, String string) throws IOException
    {
        try
        {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 是否是Ajax异步请求
     *
     * @param request
     */
    public static boolean isAjaxRequest(HttpServletRequest request)
    {
        String accept = request.getHeader("accept");
        if (accept != null && accept.contains("application/json"))
        {
            return true;
        }

        String xRequestedWith = request.getHeader("X-Requested-With");
        if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
        {
            return true;
        }

        String uri = request.getRequestURI();
        if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
        {
            return true;
        }

        String ajax = request.getParameter("__ajax");
        return StringUtils.inStringIgnoreCase(ajax, "json", "xml");
    }

    /**
     * 内容编码
     *
     * @param str 内容
     * @return 编码后的内容
     */
    public static String urlEncode(String str)
    {
        try
        {
            return URLEncoder.encode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return StringUtils.EMPTY;
        }
    }

    /**
     * 内容解码
     *
     * @param str 内容
     * @return 解码后的内容
     */
    public static String urlDecode(String str)
    {
        try
        {
            return URLDecoder.decode(str, Constants.UTF8);
        }
        catch (UnsupportedEncodingException e)
        {
            return StringUtils.EMPTY;
        }
    }
}

 

标签:return,String,request,认证,static,springboot3,new,security,public
From: https://www.cnblogs.com/fps2tao/p/18243936

相关文章

  • 认证申报 | 中华环保联合会 “全国环境友好企业”认证服务
    中华环保联合会水环境治理专业委员会秘书处联系人:王小雅电话:010-51651268 13718793867网址:www.acef-water.com.cn01什么是“全国环境友好企业”认证“全国环境友好企业”认证是经国家认证认可监督管理委员会审查监督并在全国认证认可信息公共服务平台发布公示,以中华......
  • Day25.密码加密、登录认证装饰器
    1.密码加密、登录认证装饰器_md5加密方法代码 md5加密方法代码:importhashlib#md5加密defget_pwd_md5(password):md5_obj=hashlib.md5()md5_obj.update(password.encode('utf-8'))#密码加盐salt='一二三四五'md5_obj.update(salt.enc......
  • SpringBoot3.0.x适配mybatis版本
    SpringBoot适配mybatis版本最低为3.0.3<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version><......
  • 宝塔 nginx 安装 ModSecurity 模块
    本文基于modsecurity,ubuntu系统nginx搭建环境,需要先安装modsecurity,再编译安装nginx它是一款开源的的三方模块,功能包括http流量日志,实时检测等功能。ModSecurity核心规则集(CRS)提供以下类别的保户来防止攻击。官方宣传:◆HTTPProtection(HTTP防御)-HTTP协议和本地定义使用的......
  • 关于Spring Security的CORS
    目录一、CORS是什么二、同源安全策略三、SpringSecurity中CORS的开启四、其它处理方法一、CORS是什么        CORS(Cross-OriginResourceSharing,跨源/域资源共享)是一个W3C标准,一种允许当前域(domain)的资源(比如html/js/webservice)被其他域(domain)的脚本(比如AJ......
  • 什么是SpringSecurity的认证与授权?
    在SpringSecurity框架中,认证(Authentication)和授权(Authorization)是两个核心概念,它们是实现应用安全的基石。虽然这两个术语通常一起使用,但它们描述的是两个不同的安全过程。认证(Authentication)认证是确认某个用户的身份的过程。简而言之,认证过程是用来验证用户是否是......
  • SpringSecurity如何自定义用户认证逻辑?
    在SpringSecurity中自定义用户认证逻辑通常涉及到实现你自己的UserDetailsService或使用自定义的AuthenticationProvider。下面是通过这两种方式自定义用户认证逻辑的基本演示:使用UserDetailsService自定义UserDetailsService是SpringSecurity用于从数据库、L......
  • 基础概念-认证授权会话
    1.1.  什么是认证进入移动互联网时代,大家每天都在刷手机,常用的软件有微信、支付宝、头条等,下边拿微信来举例子说明认证相关的基本概念,在初次使用微信前需要注册成为微信用户,然后输入账号和密码即可登录微信,输入账号和密码登录微信的过程就是认证。系统为什么要认证?......
  • SpringBoot3集成Knife4j生成接口文档
    导入依赖<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version></dependency>注意:SpringBoot......
  • spring security中对并发登录的处理
    本文记录的springsecurity中对并发登录的处理,是基于使用session进行登录的场景,并且只适用于单体部署的场景一、session管理策略接口SessionAuthenticationStrategy针对同一个账号多次登录的问题,springsecurity抽象出了一个接口来处理同一个用户的多个sessionpublicinterf......