• sprintboot+spring security +jwt 实现登录


    直接上代码吧

    1.maven依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.0</version>
            </dependency>    

    2.security配置类 继承WebSecurityConfigurerAdapter

    package cn.likui.study.config;
    
    import cn.likui.study.auth.JwtAuthenticationEntryPoint;
    import cn.likui.study.filters.JwtTokenFilter;
    import cn.likui.study.service.impl.SysUserDetailsServiceImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    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.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.config.http.SessionCreationPolicy;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.access.AccessDeniedHandler;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    /**
    * @Description: security配置类,配置权限相关密码.
    * @Author: ldg
    * @Date: 2020/10/14
    */
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        /**
         * 调用失败的节点配置.
         */
        @Autowired
        private JwtAuthenticationEntryPoint unauthorizedHandler;
        /**
         * 权限不够的处理对象.
         */
        @Autowired
        private AccessDeniedHandler accessDeniedHandler;
        /**
         * 获取自定义用户类.
         */
        @Autowired
        private SysUserDetailsServiceImpl sysUserDetailsService;
        /**
         * 网关拦截,获取Token
         */
        @Autowired
        private JwtTokenFilter authenticationTokenFilter;
    
        @Value("${spring.login.url}")
        private String loginUrl;
    
        @Value("${spring.logout.url}")
        private String logoutUrl;
    
        @Value("${spring.create.url}")
        private String createUrl;
    
        @Value("${spring.find.url}")
        private String findUrl;
    
    
        /**
         * 装载BCrypt密码编码器
         *
         * @return
         */
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        /**
         * 构造函数.
         * @param unauthorizedHandler
         * @param accessDeniedHandler
         * @param sysUserDetailsService
         * @param authenticationTokenFilter
         */
        @Autowired
        public SecurityConfig(JwtAuthenticationEntryPoint unauthorizedHandler,
                              JwtTokenFilter authenticationTokenFilter,
                              @Qualifier("SysAccessDeniedHandler") AccessDeniedHandler accessDeniedHandler,
                              @Qualifier("SysUserDetailsService") SysUserDetailsServiceImpl sysUserDetailsService
                              ) {
            this.unauthorizedHandler = unauthorizedHandler;
            this.accessDeniedHandler = accessDeniedHandler;
            this.sysUserDetailsService = sysUserDetailsService;
            this.authenticationTokenFilter = authenticationTokenFilter;
        }
    
        /**
         * 验证身份相关配置.
         *
         * @param authenticationManagerBuilder
         * @throws Exception
         */
        @Autowired
        public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder
                    // 设置UserDetailsService
                    .userDetailsService(this.sysUserDetailsService)
                    // 使用BCrypt进行密码的hash
                    .passwordEncoder(passwordEncoder());
        }
    
        /**
         * 设置过滤条件配置.
         *
         * @param httpSecurity
         * @throws Exception
         */
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            //set configuration.
            httpSecurity
                    .exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
                    // 由于使用的是JWT,我们这里不需要csrf.
                    .csrf().disable()
                    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                    // 基于token,所以不需要session.
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                    .authorizeRequests()
                    // 对于获取token的rest api要允许匿名访问.
                    .antMatchers(
                            loginUrl,
                            logoutUrl,
                            createUrl,
                            "/stomp/**",
                            "/test/**",
                            "/workflow/**",
                            "/blockchain/**",
                            "/error/**").permitAll()
                    // 除上面外的所有请求全部需要鉴权认证
                    .anyRequest().authenticated();
            // 禁用缓存
            httpSecurity.headers().cacheControl();
            // 添加JWT filter
            httpSecurity
                    .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                    //权限不足filter.
                    .exceptionHandling().accessDeniedHandler(accessDeniedHandler)
                    //异常处理endpoint.
                    .authenticationEntryPoint(unauthorizedHandler);
        }
    
        /**
         * 设置过滤web过滤.
         * @param web
         */
        @Override
        public void configure(WebSecurity web) {
            web.ignoring().antMatchers(
               "swagger-ui.html",
                            "**/swagger-ui.html",
                            "/favicon.ico",
                            "/**/*.css",
                            "/**/*.js",
                            "/**/*.png",
                            "/**/*.gif",
                            "/swagger-resources/**",
                            "/v2/**",
                            "/**/*.ttf");
            web.ignoring().antMatchers("/v2/api-docs",
                            "/swagger-resources/configuration/ui",
                            "/swagger-resources",
                            "/swagger-resources/configuration/security",
                            "/swagger-ui.html");
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    }

    3.调用失败的节点配置

    package cn.likui.study.auth;
    
    import cn.likui.study.entity.CodeType;
    import cn.likui.study.entity.ResponseMessage;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    import org.springframework.stereotype.Component;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.Serializable;
    
    /**
    * @Description: 认证失败之后调用的接口.验证为未登陆状态会进入此方法,认证错误.
    * @Author: ldg
    * @Date: 2020/10/14
    */
    @Slf4j
    @Component
    public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
        @Override
        public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                             AuthenticationException e) throws IOException {
    
            log.info("EntryPoint");
            log.info("认证失败:{}", e.getMessage());
            log.info("请求URI: {}", httpServletRequest.getRequestURI());
    
            httpServletResponse.setStatus(200);
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json; charset=utf-8");
    
            PrintWriter printWriter = httpServletResponse.getWriter();
            ResponseMessage<?> message = ResponseMessage.error(CodeType.TOKEN_UNAUTHORIZED);
            String body = message.toJson();
            printWriter.write(body);
            printWriter.flush();
        }
    }

    4.权限不够的处理对象

    package cn.likui.study.auth;
    
    import cn.likui.study.entity.CodeType;
    import cn.likui.study.entity.ResponseMessage;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.security.access.AccessDeniedException;
    import org.springframework.security.web.access.AccessDeniedHandler;
    import org.springframework.stereotype.Component;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
    * @Description: 权限不够调用的接口.
    * @Author: ldg
    * @Date: 2020/10/14
    */
    @Slf4j
    @Component("SysAccessDeniedHandler")
    public class SysAccessDeniedHandler implements AccessDeniedHandler {
        @Override
        public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
            //登陆状态下,权限不足执行该方法
            log.info("权限不足:" + e.getMessage());
            response.setStatus(200);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter printWriter = response.getWriter();
            ResponseMessage<?> message = ResponseMessage.error(CodeType.TOKEN_FORBIDDEN.getCode(), e.getMessage());
            String body = message.toJson();
            printWriter.write(body);
            printWriter.flush();
        }
    }

    5.网关拦截,获取Token

    package cn.likui.study.filters;
    
    import cn.likui.study.entity.CodeType;
    import cn.likui.study.entity.ResponseMessage;
    import cn.likui.study.entity.SysUserDetail;
    import cn.likui.study.utils.JwtUtil;
    import com.github.pagehelper.util.StringUtil;
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.ExpiredJwtException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMethod;
    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.io.PrintWriter;
    
    /**
    * @Description:
     * * 拦截器直接拦截请求,失败之后跳转到JWTAuthenticationEntryPoint类.
     *  * 1
     *  * token校验
    * @Author: ldg
    * @Date: 2020/10/14
    */
    @Slf4j
    @Component
    public class JwtTokenFilter extends OncePerRequestFilter {
    
        private static final String CLAIM_KEY_USER_ID = "user_id";
        private static final String CLAIM_KEY_USER_NAME = "user_name";
    
        @Value("${jwt.header}")
        private String token_header;
        @Value("${jwt.tokenHead}")
        private String safe_header;
    
        //处理options浏览器请求.
        private boolean optionsProc(HttpServletRequest request, HttpServletResponse response){
            if (RequestMethod.OPTIONS.name().equals(request.getMethod())) {   //判断如果是复杂请求,直接返回200.
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                //下面这句话很重要.
                response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization,token");
                //设置好之后,不走spring security后续链路.
                return true;
            }
            return false;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
            if (optionsProc(request, response)) {
                return;
            }
            String auth_token = request.getHeader(this.token_header);
            //前缀.
            final String auth_token_start = safe_header;
            //判断token
            if (!StringUtils.isEmpty(auth_token) && auth_token.startsWith(auth_token_start)) {
                auth_token = auth_token.substring(auth_token_start.length());
            } else {
                // 不按规范,不允许通过验证
                auth_token = null;
            }
            Claims claims = null;
            try {
                claims = JwtUtil.parseJwt(auth_token);
            } catch (ExpiredJwtException jwtException) {
                sendFailedMessage(response, CodeType.TOKEN_EXPIRED);
                return;
            } catch (Exception e) {
                chain.doFilter(request, response);
                return;
            }
            //没有获取到用户信息.
            if (claims != null && !JwtUtil.isTokenTimeout(claims) && SecurityContextHolder.getContext().getAuthentication() == null) {
                log.info("Checking authentication for issuer {}.", claims.getIssuer());
                SysUserDetail userDetail = getUserFromToken(auth_token);
                //这里需要判断userDetail中的用户是否在登陆中.等等.
                if (userDetail != null && null != (userDetail.getId())
                        && !StringUtil.isEmpty(userDetail.getUsername())) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetail, null, userDetail.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    logger.info(String.format("Authenticated userDetail %s, setting security context", userDetail.getUsername()));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
            chain.doFilter(request, response);
        }
    
    
        /**
         * 通过token返回UserDetail
         *
         * @param token
         * @return
         */
        public SysUserDetail getUserFromToken(String token) {
            SysUserDetail userDetail;
            try {
                Claims claims = JwtUtil.parseJwt(token);
                String userId = claims.get(CLAIM_KEY_USER_ID).toString();
                Object obj = claims.get(CLAIM_KEY_USER_NAME);
                String username = "";
                if(obj != null){
                    username = obj.toString();
                }
                userDetail = new SysUserDetail(Integer.valueOf(userId), username, token);
            } catch (Exception e) {
                userDetail = null;
            }
            return userDetail;
        }
    
    
        private void sendFailedMessage(HttpServletResponse response, CodeType codeType) {
            response.setStatus(200);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            try {
                PrintWriter printWriter = response.getWriter();
                ResponseMessage<?> message = ResponseMessage.error(codeType.getCode(), codeType.getDescription());
                log.error("code:{},message:{}", codeType.getCode(), codeType.getDescription());
                String body = message.toJson();
                printWriter.write(body);
                printWriter.flush();
            } catch (IOException ioe) {
                log.error(ioe.getMessage());
            }
        }
    }

    6.异常类

    package cn.likui.study.exception;
    
    import cn.likui.study.entity.ResponseMessage;
    
    /**
     * dssp security exception
     */
    public class SysSecurityException extends RuntimeException{
        private ResponseMessage message;
    
        public SysSecurityException(ResponseMessage message){
            this.message = message;
        }
    
        @Override
        public String getMessage() {
            return message.getMessage();
        }
    }

    7.请求响应类

    package cn.likui.study.entity;
    
    import com.alibaba.fastjson.JSON;
    import lombok.NoArgsConstructor;
    import java.io.Serializable;
    
    /**
     * @param <T> T:响应体数据类型
     * @author
     * 请求响应类
     */
    @NoArgsConstructor
    public class ResponseMessage<T> implements Serializable {
        private static final long serialVersionUID = 1L;
    
        /**
         * 状态码
         */
        private Integer code;
    
        /**
         * 异常信息
         */
        private String message;
    
        /**
         * 响应信息
         */
        private T data;
    
        private boolean error = false;
    
        /**
         * 是否错误.
         *
         * @return
         */
        public boolean isError() {
            return error;
        }
    
        /**
         * 构造成功消息
         *
         * @param <T> 返回数据类型
         * @return 消息
         */
        public static <T> ResponseMessage<T> success() {
            ResponseMessage msg = new ResponseMessage<T>(CodeType.SUCCESS.getCode(), CodeType.SUCCESS.getDescription(), null);
            msg.error = false;
            return msg;
        }
    
        public static <T> ResponseMessage<T> success(String message) {
            ResponseMessage msg = new ResponseMessage<T>(CodeType.SUCCESS.getCode(), message, null);
            msg.error = false;
            return msg;
        }
    
        /**
         * 构造成功消息
         *
         * @param data 返回数据
         * @param <T>  返回数据类型
         * @return 消息
         */
        public static <T> ResponseMessage<T> success(T data) {
            ResponseMessage msg = new ResponseMessage<T>(CodeType.SUCCESS.getCode(), null, data);
            msg.error = false;
            return msg;
        }
    
        /**
         * 构造错误消息
         *
         * @param errorCode    异常状态码
         * @param errorMessage 异常描述信息
         * @return 消息
         */
        public static ResponseMessage<?> error(Integer errorCode, String errorMessage) {
            ResponseMessage msg = new ResponseMessage(errorCode, errorMessage, null);
            msg.error = true;
            return msg;
        }
    
        public static ResponseMessage<?> error(CodeType type) {
            ResponseMessage msg = new ResponseMessage(type.getCode(), type.getDescription(), null);
            msg.error = true;
            return msg;
        }
    
        public static ResponseMessage<?> error(CodeType type, String errorMessage) {
            ResponseMessage msg = new ResponseMessage(type.getCode(), errorMessage, null);
            msg.error = true;
            return msg;
        }
    
        /**
         * to json.
         *
         * @return
         */
        public String toJson() {
            return this == null ? "" : JSON.toJSONString(this);
        }
    
    
        /**
         * 私有构造器
         *
         * @param code    状态码
         * @param message 状态描述
         * @param data    数据
         */
        private ResponseMessage(Integer code, String message, T data) {
            this.code = code;
            this.message = message;
            this.data = data;
            this.error = false;
        }
    
        public ResponseMessage(CodeType codeType, T data, boolean isError) {
            this.code = codeType.getCode();
            this.message = codeType.getDescription();
            this.data = data;
            this.error = isError;
        }
    
        /**
         * 获取状态码
         *
         * @return 状态码
         */
        public Integer getCode() {
            return code;
        }
    
        /**
         * 获取异常描述信息
         *
         * @return 异常描述信息
         */
        public String getMessage() {
            return message;
        }
    
        /**
         * 获取返回数据
         *
         * @return 返回数据
         */
        public T getData() {
            return data;
        }
    
    
    }

    9.枚举

    package cn.likui.study.entity;
    
    /**
     * 异常代码描述。
     * @author
     */
    public enum CodeType {
    
    
        //参数
        UNKNOWN_ERROR(1000, "未知错误"),
        
        TOKEN_EXPIRED(2000, "Token过期"),
        TOKEN_EXCEPTION(2001, "Token异常"),
        TOKEN_BLACLIST(2002, "当前用户已列入黑名单"),
        TOKEN_REGISTERED(2003, "当前用户已经注册"),
        TOKEN_REGISTER_FAIL(2004, "用户注册失败"),
        TOKEN_UNAUTHORIZED(2005, "认证失败"),
        TOKEN_FORBIDDEN(2006, "权限不足"),
        TOKEN_PARAMETER_ERROR(2007, "参数错误"),
        ERROR_LOGIN_EMAIL(2008, "用户邮箱未注册"),
        
    
        /**
         * 错误编码
         */
        private Integer code;
        /**
         * 错误描述
         */
        private String description;
    
        private CodeType(Integer code, String description) {
            this.code = code;
            this.description = description;
        }
    
        /**
         * 根据错误编码实例
         *
         * @param code 错误编码
         * @return 实例
         */
        public static CodeType getErrorCode(Integer code) {
            for (CodeType errorCode : CodeType.values()) {
                if (errorCode.getCode().equals(code)) {
                    return errorCode;
                }
            }
            return CodeType.UNKNOWN_ERROR;
        }
    
        public Integer getCode() {
            return code;
        }
    
        public void setCode(Integer code) {
            this.code = code;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    }

    10.入参对象

    /**
    * @Description:
    * @Author: ldg
    * @Date: 2020/10/15
    */
    @Data
    public class LoginEntity {
        private String loginEmail;
        private String phone;
        private String oldPassword;
        private String password;
    }

    11.控制层登录方法注册方法

    package cn.likui.study.controller;
    
    import cn.likui.study.entity.CodeType;
    import cn.likui.study.entity.LoginEntity;
    import cn.likui.study.entity.ResponseMessage;
    import cn.likui.study.entity.SysUserDetail;
    import cn.likui.study.mapper.SysUserMapper;
    import cn.likui.study.service.AuthService;
    import cn.likui.study.utils.JwtUtil;
    import com.alibaba.fastjson.JSONObject;
    import com.github.pagehelper.util.StringUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 权限认证controller
     *
     * @author
     */
    @Slf4j
    @RestController
    @RequestMapping("/gateway")
    public class AuthController {
    
        @Value("${jwt.header}")
        private String strTokenHeader;
    
        @Value("${jwt.tokenHead}")
        private String safe_header;
    
        private final String HEADER_AUTHORIZATION = "Authorization";
    
        @Autowired
        AuthService service;
    //    @Resource
    //    SysUserMapper mapper;
    
        /**
         * 修改密码.
         * @param loginEntity
         * @return
         */
        @PostMapping("/changePassword")
        public ResponseMessage changePassword(@RequestBody LoginEntity loginEntity) {
    
            ResponseMessage msg = null;
    
            //用户名(手机或者邮箱),新密码,旧密码.
            if (null == loginEntity
                    || StringUtils.isBlank(loginEntity.getOldPassword())
                    || StringUtils.isBlank(loginEntity.getPassword()) ) {
                return ResponseMessage.error(CodeType.MISSING_PARAME);
            } else {
                if (StringUtils.isBlank(loginEntity.getPhone()) && StringUtils.isBlank(loginEntity.getLoginEmail()) ) {
                    return ResponseMessage.error(CodeType.MISSING_PARAME);
                }
            }
    
            String userName = StringUtil.isNotEmpty(loginEntity.getLoginEmail()) ? loginEntity.getLoginEmail() : loginEntity.getPhone();
            try {
                SysUserDetail userDetail = service.login(userName, loginEntity.getOldPassword());
                msg = verifyDsspUserDetail(userDetail);
                if(!msg.isError()){
                    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
                    String encode = encoder.encode(loginEntity.getPassword());
                    Integer state = 1;
    //                Integer state = mapper.updatePassword(loginEntity.getLoginEmail(), loginEntity.getPhone(), encode);
                    if (state > 0) {
                        return ResponseMessage.success();
                    } else {
                        return ResponseMessage.error(CodeType.CHANGE_PASSWORD_ERROR);
                    }
    
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                return ResponseMessage.error(CodeType.ERROR_OLD_PASSWORD);
            }
    
            return ResponseMessage.error(CodeType.ERROR_OLD_PASSWORD);
        }
    
    
        private ResponseMessage verifyDsspUserDetail(SysUserDetail userDetail) {
            ResponseMessage<?> msg = null;
            if (userDetail == null) {
                return ResponseMessage.error(CodeType.SMS_CODE_ERROR_USER_NOT_EXIST);
            }
    //        if (Constants.USER_STATUS_DISABLED.equals(userDetail.getDisableFlag())) {
    //            return ResponseMessage.error(UserState.Disabled.getCode(), UserState.Disabled.getDescription());
    //        }
    //        if (Constants.USER_LOGIN_STATUS_OK.equals(userDetail.getLoginStatus())) {
    //            return ResponseMessage.error(UserState.LOGIN_JOBING.getCode(), UserState.LOGIN_JOBING.getDescription());
    //        }
    
            String token = userDetail.getToken();
            token = safe_header + token;
            userDetail.setToken(token);
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = attributes.getResponse();
            //没必要.
            this.setTokenToHeader(response, userDetail.getToken());
            msg = ResponseMessage.success(userDetail);
    
            return msg;
        }
    
        /**
        * @Description: 登录
        * @Author: ldg
        * @Date: 2020/10/15
        */
        @PostMapping("/login")
        public ResponseMessage login(@RequestBody LoginEntity loginEntity) {
    
            log.info("login params:{}", JSONObject.toJSONString(loginEntity));
            String userName = StringUtil.isNotEmpty(loginEntity.getLoginEmail()) ? loginEntity.getLoginEmail() : loginEntity.getPhone();
    
            ResponseMessage<?> msg = null;
            try {
                SysUserDetail userDetail = service.login(userName, loginEntity.getPassword());
                msg = verifyDsspUserDetail(userDetail);
    //            //更新小程序用的id
    //            if(!msg.isError()){
    //                if (!StringUtils.isEmpty(loginEntity.getOpenId())) {
    //                    service.updateUserOpenId(loginEntity);
    //                }
    //            }
                if(!msg.isError()){
                    if (!StringUtils.isEmpty(loginEntity.getPhone()) || !StringUtils.isEmpty(loginEntity.getLoginEmail())) {
                        loginEntity.setLoginStatus(1);
                        service.updateLoginStatus(loginEntity);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                return ResponseMessage.error(CodeType.ERROR_PASSWORD.getCode(), CodeType.ERROR_PASSWORD.getDescription());
            }
            return msg;
        }
    
        private void setTokenToHeader(HttpServletResponse response, String token) {
            response.setHeader(strTokenHeader, token);
        }
    
        /**
         * @RequestParam String username
         * @return
         */
    //    @ApiOperation("登出")
        @PostMapping("/logout")
        public ResponseMessage logout(@RequestBody LoginEntity loginEntity) {
    
            if (StringUtils.isBlank(loginEntity.getPhone())) {
                return ResponseMessage.error(CodeType.LOGOUT_FAIL.getCode(), CodeType.LOGOUT_FAIL.getDescription());
            }
            loginEntity.setLoginStatus(0);
            service.updateLoginStatus(loginEntity);
            return ResponseMessage.success("logout");
        }
    
    //    @Deprecated
    //    @ApiOperation("注册")
    //    @PostMapping("/register")
    //    public ResponseMessage register(@RequestBody LoginEntity loginEntity) {
    //        if (StringUtils.isAnyBlank(loginEntity.getPassword())) {
    //            return ResponseMessage.error(CodeType.TOKEN_PARAMETER_ERROR.getCode(),
    //                    CodeType.TOKEN_PARAMETER_ERROR.getDescription());
    //        }
    //        //验证手机号
    //        if (StringUtil.isNotEmpty(loginEntity.getPhone()) && !CheckUtil.isPhone(loginEntity.getPhone())) {
    //            return ResponseMessage.error(CodeType.PHONE_ERROR.getCode(), CodeType.PHONE_ERROR.getDescription());
    //        }
    //
    ////        Role role = new Role();
    ////        role.setRoleId(loginEntity.getRoleId());
    //        DsspUserDetail userDetail = new DsspUserDetail(loginEntity.getLoginEmail(),
    //                loginEntity.getPassword(),
    //                loginEntity.getPhone(),
    //                loginEntity.getCompanyId());
    //        String username = null;
    //        if(StringUtil.isEmpty(loginEntity.getUserName())){
    //            if(StringUtil.isEmpty(loginEntity.getLoginEmail()) || StringUtil.isEmpty(loginEntity.getPhone())){
    //                return ResponseMessage.error(CodeType.MISSING_PARAME);
    //            }else{
    //                if(StringUtil.isNotEmpty(loginEntity.getLoginEmail())){
    //                    username = loginEntity.getLoginEmail();
    //                }else{
    //                    username = loginEntity.getPhone();
    //                }
    //            }
    //        }else {
    //            username = loginEntity.getUserName();
    //        }
    //        userDetail.setUsername(username);
    //        userDetail.setEmail(StringUtils.isNoneBlank(loginEntity.getLoginEmail()) ? loginEntity.getLoginEmail() : "");
    //        userDetail.setCompanyType(loginEntity.getCompanyType());
    //        //冗余一下.
    //        userDetail.setPlatId(loginEntity.getCompanyType());
    //        try {
    //            userDetail = service.register(userDetail);
    //        } catch (Exception ex) {
    //            return ResponseMessage.error(CodeType.REGISTER_DSP_ERROR, ex.getMessage());
    //        }
    //        ResponseMessage<Integer> msg = ResponseMessage.success(Integer.valueOf(userDetail.getId()));
    //        return msg;
    //    }
    
    
    //    @ApiOperation("根据token返回用户信息.")
        @PostMapping("/findByToken")
        public ResponseMessage<SysUserDetail> findByToken() {
            //获取token
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String token = request.getHeader(HEADER_AUTHORIZATION);
            String userId = JwtUtil.getUserIdFromToken(token);
    
            if (StringUtil.isEmpty(userId)) {
                return null;
            } else {
                SysUserDetail userVO = new SysUserDetail();
                userVO.setId(Integer.parseInt(userId));
    //            userVO = mapper.getUserVO(userVO);
    
                SysUserDetail userDetail = new SysUserDetail();
    //            userDetail = userDetail.bulidDsspUserDetail(userDetail,userVO,mapper.getRoleList(userVO),mapper.getRuleList(userVO));
    
    //            if (userDetail == null) {
    //                ResponseMessage<BaseUser> err = new ResponseMessage<BaseUser>(CodeType.TOKEN_UNAUTHORIZED, null, false);
    //                return err;
    //            }
                ResponseMessage<SysUserDetail> result = ResponseMessage.success(userDetail);
                return result;
            }
        }
    
    //    @Deprecated
    //    @ApiOperation("根据platId返回企业用户信息.")
    //    @PostMapping("/getUsersByPlatId")
    //    public ResponseMessage<?> getUsersByPlatId(Integer platId, String companyName) {
    //        List<DsspUserDetail> users;
    //        if (platId.equals(PlatIds.dsp) || platId.equals(PlatIds.ssp)) {
    //            users = mapper.findUsersByPlatId(platId, companyName);
    //        } else {
    //            return ResponseMessage.error(CodeType.MISSING_PARAME);
    //        }
    //
    //        if (users != null) {
    //            List<BaseUser> lst = new ArrayList<>();
    //            users.forEach((ele) -> {
    ////                lst.add(ele.buildBaseUser());
    //            });
    //            ResponseMessage<List<BaseUser>> rsp = ResponseMessage.success(lst);
    //            return rsp;
    //        } else {
    //            return ResponseMessage.error(CodeType.MISSING_PARAME);
    //        }
    //    }
    
    //    @Deprecated
    //    @ApiOperation("获取用户的openid")
    //    @PostMapping("/getWeixinOpenId")
    //    public ResponseMessage getWeixinOpenId(@RequestBody JSONObject jsonObject) {
    //        String jsCode = jsonObject.getString("jsCode");
    //        String url = String.format(weixinUrl, jsCode);
    //        RestTemplate restTemplate = new RestTemplate();
    //        String resp = restTemplate.getForObject(url, String.class);
    //        String openId = getOpenId(resp);
    //        if (StringUtils.isEmpty(openId)) {
    //            return ResponseMessage.error(CodeType.WEIXIN_LOGIN_ERROR, resp);
    //        }
    //        JSONObject result = new JSONObject();
    //        DsspUserDetail userDetail = service.getUserDetailForOpenId(openId);
    //        boolean exist = userDetail != null;
    //        result.put("exist", exist);
    //        result.put("openId", openId);
    //        if (!exist) {
    //            return ResponseMessage.success(result);
    //        } else {
    //            return ResponseMessage.success(result);
    //        }
    //    }
    //
    //    private String getOpenId(String txResp) {
    //        JSONObject json = JSONObject.parseObject(txResp);
    //        if (json.containsKey("errcode")) {
    //            return StringUtils.EMPTY;
    //        }
    //        return json.getString("openid");
    //    }
    
    //    @ApiOperation("测试")
    //    @PostMapping("/hello")
    //    public ResponseMessage<DsspUserDetail> hello() {
    //        log.info("-------------------hello-------------------");
    //        return ResponseMessage.success();
    //    }
    
    //    /**
    //     * 扫码状态.
    //     *
    //     * @return
    //     */
    //    @Deprecated
    //    @PostMapping("/QRLoginState")
    //    public ResponseMessage loginState(@RequestBody JSONObject params) {
    //        String key = params.getString("key");
    //        ThreeParam threeParam = templateManager.getData(TemplateIds.mobile_login, key, ThreeParam.class);
    //        if (threeParam == null) {
    //            //二维码失效.
    //            return ResponseMessage.success(0);
    //        } else if (StringUtils.isEmpty(threeParam.getParam2())) {
    //            //等待扫码.
    //            return ResponseMessage.success(1);
    //        } else {
    //            //扫码成功.
    //            return ResponseMessage.success(threeParam.getParam3());
    //        }
    //    }
    
    //    /**
    //     * 扫码.
    //     *
    //     * @param params
    //     * @return
    //     */
    //    @Deprecated
    //    @PostMapping("/scanQR")
    //    public ResponseMessage scanQR(@RequestBody JSONObject params) {
    //        String key = params.getString("key");
    //        String token = params.getString("token");
    //        ThreeParam param = templateManager.getData(TemplateIds.mobile_login, key, ThreeParam.class);
    //        if (param == null) {
    //            return ResponseMessage.error(CodeType.QR_FAILED);
    //        } else {
    //            //传递token设置.
    //            String userId = JwtUtil.getUserIdFromToken(token);
    //            param.setParam2(userId);
    //            param.setParam3(token);
    //            boolean b = templateManager.updateRedis(TemplateIds.mobile_login, param);
    //            return ResponseMessage.success(b);
    //        }
    //    }
    
        /**
         * 通过token进行登录.
         *
         * @param params
         * @return
         */
        @PostMapping("/loginFromToken")
        public ResponseMessage loginFromToken(@RequestBody JSONObject params) {
            String token = params.getString("token");
            if (StringUtils.isEmpty(token)) {
                return ResponseMessage.success(CodeType.QR_LOGIN_ERROR);
            }
            String userId = JwtUtil.getUserIdFromToken(token);
            if (StringUtils.isEmpty(userId)) {
                return ResponseMessage.success(CodeType.QR_LOGIN_ERROR);
            }
            SysUserDetail userVO = new SysUserDetail();
            userVO.setId(Integer.parseInt(userId));
    //        userVO = mapper.getUserVO(userVO);
    
            SysUserDetail userDetail = new SysUserDetail();
    //        userDetail = userDetail.bulidDsspUserDetail(userDetail,userVO,mapper.getRoleList(userVO),mapper.getRuleList(userVO));
            userDetail.setToken(token);
            return ResponseMessage.success(userDetail);
        }
    
    //    public static void main(String[] args) {
    //        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    //        String s = encoder.encode("a12345");
    //        log.info("s={}",s);
    //    }
    
    }
    View Code

    12.业务层

    package cn.likui.study.service.impl;
    
    import cn.likui.study.enums.CodeType;
    import cn.likui.study.entity.LoginEntity;
    import cn.likui.study.entity.ResponseMessage;
    import cn.likui.study.entity.SysUserDetail;
    import cn.likui.study.exception.SysSecurityException;
    import cn.likui.study.mapper.SysUserMapper;
    import cn.likui.study.service.AuthService;
    import cn.likui.study.utils.JwtUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.BadCredentialsException;
    import org.springframework.security.authentication.DisabledException;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.stereotype.Service;
    
    /**
     * authservice实现类.
     * 角色注册,登陆等核心service.
     * 2
     */
    @Slf4j
    @Service
    public class AuthServiceImpl implements AuthService {
    
        private final AuthenticationManager authenticationManager;
        private final UserDetailsService userDetailsService;
        private final SysUserMapper sysUserMapper;
    //    @Autowired
    //    private TemplateManager templateManager;
    
        @Autowired
        public AuthServiceImpl(AuthenticationManager authenticationManager,
                               @Qualifier("SysUserDetailsService") UserDetailsService userDetailsService,
                               SysUserMapper sysUserMapper) {
            this.authenticationManager = authenticationManager;
            this.userDetailsService = userDetailsService;
            this.sysUserMapper = sysUserMapper;
        }
    
        /**
         * 登录方法,过滤器只开放这个接口.
         * 调用之后会进入SpringSecurity认证体系.
         *
         * @param username
         * @param password
         * @return
         */
        @Override
        public SysUserDetail login(String username, String password) {
            //权限对象,会调用(UserDetailsService.loadUserByUsername)
            final Authentication authentication = authenticate(username, password);
            //存储到上下文中.
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //到这里就算登陆ok了.
            final SysUserDetail userDetail = (SysUserDetail) authentication.getPrincipal();
            //生成token,会调用方法.(id,登陆账号).
            final String token = JwtUtil.createJwtToken(userDetail.getId(), username);
            log.info("-----------------------------generateAccessToken:{}", token);
            //token进行存储.
            userDetail.setToken(token);
    
            return userDetail;
        }
    templateManager.updateRedis(TemplateIds.mobile_login, twoParam, timeoutSecond);
    //        }
    //    }
    
        /**
         * 该方法会去调用userDetailsService.loadUserByUsername()
         * 去验证用户名和密码,如果正确,则存储该用户名密码到“security 的 context中”
         * 2
         *
         * @param username
         * @param password
         * @return
         */
        private Authentication authenticate(String username, String password) {
            try {
                UsernamePasswordAuthenticationToken tokenService = new UsernamePasswordAuthenticationToken(username, password);
                Authentication auth = authenticationManager.authenticate(tokenService);
                return auth;
            } catch (DisabledException | BadCredentialsException e) {
                throw new SysSecurityException(ResponseMessage.error(CodeType.TOKEN_UNAUTHORIZED.getCode(), e.getMessage()));
            }
        }
    
    
    }
    View Code

    13.登陆身份认证 

    package cn.likui.study.service.impl;
    
    import cn.likui.study.entity.SysUser;
    import cn.likui.study.entity.SysUserDetail;
    import cn.likui.study.mapper.SysUserMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Component;
    import javax.annotation.Resource;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 登陆身份认证.
     * 通过用户名获取用户对象.
     * 根据用户名获取数据库该用户信息,spring security在登录时自动调用
     * WebSecurityConfigurerAdapter会拿这里的User里的password与用户输入的对比验证
     * 3
     * @author
     */
    @Slf4j
    @Component(value = "SysUserDetailsService")
    public class SysUserDetailsServiceImpl implements UserDetailsService {
    
        @Resource
        private SysUserMapper sysUserMapper;
    
        /**
         * 核心验证用户方法.(security框架调用)
         * 3
         * @param userName
         * @return
         * @throws UsernameNotFoundException
         */
        @Override
        public SysUserDetail loadUserByUsername(String userName) throws UsernameNotFoundException {
    
            SysUser sysUser = new SysUser();
            sysUser.setUserName(userName);
            //TODO 查询数据
            sysUser = sysUserMapper.selectByPrimaryKey(null);
            if(sysUser == null){
                log.warn("------------------------用户不存在.-------------------------");
                return null;
            }
    
            SysUserDetail userDetail = new SysUserDetail();
            //TODO sysUser beanUtils copy  userDetail
    
            //权限集合.(本系统直接通过mysql获取,放置到role中.
            //设置权限(目前没用,随便设一个).
            List<GrantedAuthority> lstAuths = new ArrayList<>();
            lstAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
            userDetail.setAuthorities(lstAuths);
    
    //        List<RoleVO> roleVOs = authMapper.getRoleList(userVO);
    //        List<RuleVO> ruleVOs = authMapper.getRuleList(userVO);
    //        userDetail = userDetail.bulidDsspUserDetail(userDetail,userVO,roleVOs,ruleVOs);
            log.info("SysUserDetail:", userDetail);
            return userDetail;
        }
    }
    View Code
  • 相关阅读:
    BZOJ2061 : Country
    BZOJ3591: 最长上升子序列
    BZOJ4356 : Ceoi2014 Wall
    BZOJ2159 : Crash 的文明世界
    BZOJ2149 : 拆迁队
    BZOJ2739 : 最远点
    BZOJ4068 : [Ctsc2015]app
    BZOJ4361 : isn
    BZOJ4404 : [Neerc2015]Binary vs Decimal
    BZOJ4402 : Claris的剑
  • 原文地址:https://www.cnblogs.com/beixiaoyi/p/13820142.html
Copyright © 2020-2023  润新知