美文网首页
SpringBoot 整合security 实现自定义Token

SpringBoot 整合security 实现自定义Token

作者: 猫的树 | 来源:发表于2021-06-09 09:31 被阅读0次

    接上一篇
    6.认证相关处理创建
    登录成功 DemoAuthenticationSuccessHandler.java

    /**
     * 用户身份验证通过处理
     */
    @Component
    @SuppressWarnings("all")
    public class DemoAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    
        @Autowired
        private TokenService tokenService;
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                                            HttpServletResponse httpServletResponse,
                                            Authentication authentication) throws IOException, ServletException {
            // 取得认证用户信息
            UserDetailsInfo userInfo = (UserDetailsInfo) authentication.getDetails();
    
            // 设置用户返回信息
            UserInfoOutputDto outputDto = new UserInfoOutputDto();
            String username = userInfo.getUsername();
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            outputDto.setRole(userInfo.getRole());
            outputDto.setLoginTime(dateFormat.format(date));
            outputDto.setUserId(userInfo.getUserId());
            outputDto.setUserName(userInfo.getUsername());
    
            // 创建Token
            userInfo.setIp(ClientIdUtil.getIp(httpServletRequest));
            TokenInfo tokenInfo = tokenService.createToken(userInfo);
    
            outputDto.setClientId(tokenInfo.getClientId());
            outputDto.setAccessToken(tokenInfo.getAccessToken());
            ResultData data = new ResultData(1, "login successful", outputDto);
            Gson gson = new Gson();
            httpServletResponse.getWriter().write(gson.toJson(data));
        }
    }
    

    UserInfoOutputDto.java

    /**
     * 用户登录返回信息
     */
    public class UserInfoOutputDto {
        private String userId;
        private String userName;
        private String role;
        private String clientId;
        private String accessToken;
        private String loginTime;
        ...
    

    登录失败 DemoAuthenticationFailureHandler.java

    /**
     * 用户身份验证失败处理
     */
    @Component
    public class DemoAuthenticationFailureHandler implements AuthenticationFailureHandler {
        @Override
        public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
                                            HttpServletResponse httpServletResponse,
                                            AuthenticationException e) throws IOException, ServletException {
            PermissionJsonException jsonException = new PermissionJsonException();
            if (e instanceof UsernameNotFoundException) {
                jsonException.setCode(10001);
                jsonException.setMsg("username not exits");
            } else if (e instanceof BadCredentialsException) {
                jsonException.setCode(10002);
                jsonException.setMsg("wrong password ");
            } else if (e instanceof DisabledException) {
                jsonException.setCode(10003);
                jsonException.setMsg("user is disabled");
            } else {
                jsonException.setCode(10004);
                jsonException.setMsg("error");
            }
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            Gson gson = new Gson();
            httpServletResponse.getWriter().write(gson.toJson(jsonException));
        }
    }
    

    账号同时登录处理 DemoExpiredHandler.java

    /**
     * 账号同时登录处理
     */
    @Component
    @SuppressWarnings("all")
    public class DemoExpiredHandler implements SessionInformationExpiredStrategy {
    
        @Autowired
        private TokenService tokenService;
    
        @Override
        public void onExpiredSessionDetected(SessionInformationExpiredEvent
                                                 sessionInformationExpiredEvent) throws IOException, ServletException {
            // 获取登录的token信息
            String clientId = sessionInformationExpiredEvent.getRequest().getHeader("clientId");
            TokenInfo tokenInfo = tokenService.findByClientId(clientId);
            // 设置账户登录信息
            ExpiredData expiredData = new ExpiredData();
            // 登录ip
            expiredData.setIp(tokenInfo.getIp());
            SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm");
            // 登录时间
            expiredData.setLoginTime(dateFormat.format(tokenInfo.getUpdateTime()));
            Gson gson = new Gson();
            sessionInformationExpiredEvent.getResponse().getWriter().write(gson.toJson(expiredData));
        }
    }
    

    ExpiredData.java

    /**
     * 重复登录信息
     */
    public class ExpiredData {
        /**
         * 登录ip
         */
        private String ip;
        /**
         * 登录时间
         */
        private String loginTime;
    
        public String getIp() {
            return ip;
        }
    
        public void setIp(String ip) {
            this.ip = ip;
        }
    
        public String getLoginTime() {
            return loginTime;
        }
    
        public void setLoginTime(String loginTime) {
            this.loginTime = loginTime;
        }
    }
    

    重点来了

    7.Security配置

    package com.example.demo.base.config;
    
    import com.example.demo.base.common.DemoAuthenticationFailureHandler;
    import com.example.demo.base.common.DemoAuthenticationProvider;
    import com.example.demo.base.common.DemoAuthenticationSuccessHandler;
    import com.example.demo.base.common.DemoExpiredHandler;
    import com.example.demo.base.common.DemoLogoutSuccessHandler;
    import com.example.demo.base.filter.SecurityFilter;
    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.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
    
    /**
     * Security配置
     */
    @Configuration
    @SuppressWarnings("all")
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private DemoAuthenticationProvider demoAuthenticationProvider;
        @Autowired
        private DemoAuthenticationFailureHandler failureHandler;
        @Autowired
        private DemoAuthenticationSuccessHandler successHandler;
        @Autowired
        private DemoLogoutSuccessHandler logoutSuccessHandler;
        @Autowired
        private DemoExpiredHandler expiredHandler;
    
        /**
         * 验证用户密码
         * @param auth
         * @throws Exception
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(demoAuthenticationProvider);
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/favicon.ico").permitAll()
                // 请求需要身份认证
                .anyRequest().authenticated()
                // 配置登录页面
                .and().formLogin()
                .loginPage("/nopermission")
                // 登录请求url
                .loginProcessingUrl("/login")
                // 身份验证成功/失败 处理
                .successHandler(successHandler).failureHandler(failureHandler).permitAll()
                // 退出登录处理
                .and().logout().logoutUrl("/logout")
                .logoutSuccessHandler(logoutSuccessHandler)
                .deleteCookies("JSESSIONID")
                .and().addFilterAt(securityFilter(), FilterSecurityInterceptor.class).exceptionHandling()
                // 相同账号的最大用户数
                .and().sessionManagement().maximumSessions(1)
                .expiredSessionStrategy(expiredHandler);
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/**");
        }
    
        @Bean
        SecurityFilter securityFilter() {
            return new SecurityFilter();
            // 这个方法才能在拦截器中自动注入查询数据库的对象
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    }
    
    

    代码写到这,一个实现Token验证的登录就写好了,下一篇我们可以测试一下是否成功。

    相关文章

      网友评论

          本文标题:SpringBoot 整合security 实现自定义Token

          本文链接:https://www.haomeiwen.com/subject/lrxdsltx.html