• 登录接口的实现


            <!-- spring security -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <!-- jwt -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
    package com.louis.mango.admin.controller;
    
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.google.code.kaptcha.Constants;
    import com.google.code.kaptcha.Producer;
    import com.louis.mango.admin.model.SysUser;
    import com.louis.mango.admin.security.JwtAuthenticatioToken;
    import com.louis.mango.admin.service.SysUserService;
    import com.louis.mango.admin.util.PasswordUtils;
    import com.louis.mango.admin.util.SecurityUtils;
    import com.louis.mango.admin.vo.LoginBean;
    import com.louis.mango.common.utils.IOUtils;
    import com.louis.mango.core.http.HttpResult;
    
    /**
     * 登录控制器
     * 
     * @author Louis
     * @date Jan 14, 2019
     */
    @RestController
    public class SysLoginController {
    
        @Autowired
        private Producer producer;
        @Autowired
        private SysUserService sysUserService;
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @GetMapping("captcha.jpg")
        public void captcha(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {
            response.setHeader("Cache-Control", "no-store, no-cache");
            response.setContentType("image/jpeg");
    
            // 生成文字验证码
            String text = producer.createText();
            // 生成图片验证码
            BufferedImage image = producer.createImage(text);
            // 保存到验证码到 session
            request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
    
            ServletOutputStream out = response.getOutputStream();
            ImageIO.write(image, "jpg", out);
            IOUtils.closeQuietly(out);
        }
    
        /**
         * 登录接口
         */
        @PostMapping(value = "/login")
        public HttpResult login(@RequestBody LoginBean loginBean, HttpServletRequest request) throws IOException {
            String username = loginBean.getAccount();
            String password = loginBean.getPassword();
            String captcha = loginBean.getCaptcha();
            // 从session中获取之前保存的验证码跟前台传来的验证码进行匹配
            Object kaptcha = request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
            if (kaptcha == null) {
                return HttpResult.error("验证码已失效");
            }
            if (!captcha.equals(kaptcha)) {
                return HttpResult.error("验证码不正确");
            }
            // 用户信息
            SysUser user = sysUserService.findByName(username);
            // 账号不存在、密码错误
            if (user == null) {
                return HttpResult.error("账号不存在");
            }
            if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) {
                return HttpResult.error("密码不正确");
            }
            // 账号锁定
            if (user.getStatus() == 0) {
                return HttpResult.error("账号已被锁定,请联系管理员");
            }
            // 系统登录认证
            JwtAuthenticatioToken token = SecurityUtils.login(request, username, password, authenticationManager);
            return HttpResult.ok(token);
        }
    
    }
    package com.louis.mango.admin.util;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
    
    import com.louis.mango.admin.security.JwtAuthenticatioToken;
    
    /**
     * Security相关操作
     * @author Louis
     * @date Jan 14, 2019
     */
    public class SecurityUtils {
    
        /**
         * 系统登录认证
         * @param request
         * @param username
         * @param password
         * @param authenticationManager
         * @return
         */
        public static JwtAuthenticatioToken login(HttpServletRequest request, String username, String password, AuthenticationManager authenticationManager) {
            JwtAuthenticatioToken token = new JwtAuthenticatioToken(username, password);
            token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            // 执行登录认证过程
            Authentication authentication = authenticationManager.authenticate(token);
            // 认证成功存储认证信息到上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // 生成令牌并返回给客户端
            token.setToken(JwtTokenUtils.generateToken(authentication));
            return token;
        }
    
        /**
         * 获取令牌进行认证
         * @param request
         */
        public static void checkAuthentication(HttpServletRequest request) {
            // 获取令牌并根据令牌获取登录认证信息
            Authentication authentication = JwtTokenUtils.getAuthenticationeFromToken(request);
            // 设置登录认证信息到上下文
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    
        /**
         * 获取当前用户名
         * @return
         */
        public static String getUsername() {
            String username = null;
            Authentication authentication = getAuthentication();
            if(authentication != null) {
                Object principal = authentication.getPrincipal();
                if(principal != null && principal instanceof UserDetails) {
                    username = ((UserDetails) principal).getUsername();
                }
            }
            return username;
        }
        
        /**
         * 获取用户名
         * @return
         */
        public static String getUsername(Authentication authentication) {
            String username = null;
            if(authentication != null) {
                Object principal = authentication.getPrincipal();
                if(principal != null && principal instanceof UserDetails) {
                    username = ((UserDetails) principal).getUsername();
                }
            }
            return username;
        }
        
        /**
         * 获取当前登录信息
         * @return
         */
        public static Authentication getAuthentication() {
            if(SecurityContextHolder.getContext() == null) {
                return null;
            }
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return authentication;
        }
        
    }
    package com.louis.mango.admin.util;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    
    import com.louis.mango.admin.security.GrantedAuthorityImpl;
    import com.louis.mango.admin.security.JwtAuthenticatioToken;
    
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    /**
     * JWT工具类
     * @author Louis
     * @date Jan 14, 2019
     */
    public class JwtTokenUtils implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
        /**
         * 用户名称
         */
        private static final String USERNAME = Claims.SUBJECT;
        /**
         * 创建时间
         */
        private static final String CREATED = "created";
        /**
         * 权限列表
         */
        private static final String AUTHORITIES = "authorities";
        /**
         * 密钥
         */
        private static final String SECRET = "abcdefgh";
        /**
         * 有效期12小时
         */
        private static final long EXPIRE_TIME = 12 * 60 * 60 * 1000;
    
        /**
         * 生成令牌
         *
         * @param userDetails 用户
         * @return 令牌
         */
        public static String generateToken(Authentication authentication) {
            Map<String, Object> claims = new HashMap<>(3);
            claims.put(USERNAME, SecurityUtils.getUsername(authentication));
            claims.put(CREATED, new Date());
            claims.put(AUTHORITIES, authentication.getAuthorities());
            return generateToken(claims);
        }
    
        /**
         * 从数据声明生成令牌
         *
         * @param claims 数据声明
         * @return 令牌
         */
        private static String generateToken(Map<String, Object> claims) {
            Date expirationDate = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, SECRET).compact();
        }
    
        /**
         * 从令牌中获取用户名
         *
         * @param token 令牌
         * @return 用户名
         */
        public static String getUsernameFromToken(String token) {
            String username;
            try {
                Claims claims = getClaimsFromToken(token);
                username = claims.getSubject();
            } catch (Exception e) {
                username = null;
            }
            return username;
        }
        
        /**
         * 根据请求令牌获取登录认证信息
         * @param token 令牌
         * @return 用户名
         */
        public static Authentication getAuthenticationeFromToken(HttpServletRequest request) {
            Authentication authentication = null;
            // 获取请求携带的令牌
            String token = JwtTokenUtils.getToken(request);
            if(token != null) {
                // 请求令牌不能为空
                if(SecurityUtils.getAuthentication() == null) {
                    // 上下文中Authentication为空
                    Claims claims = getClaimsFromToken(token);
                    if(claims == null) {
                        return null;
                    }
                    String username = claims.getSubject();
                    if(username == null) {
                        return null;
                    }
                    if(isTokenExpired(token)) {
                        return null;
                    }
                    Object authors = claims.get(AUTHORITIES);
                    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
                    if (authors != null && authors instanceof List) {
                        for (Object object : (List) authors) {
                            authorities.add(new GrantedAuthorityImpl((String) ((Map) object).get("authority")));
                        }
                    }
                    authentication = new JwtAuthenticatioToken(username, null, authorities, token);
                } else {
                    if(validateToken(token, SecurityUtils.getUsername())) {
                        // 如果上下文中Authentication非空,且请求令牌合法,直接返回当前登录认证信息
                        authentication = SecurityUtils.getAuthentication();
                    }
                }
            }
            return authentication;
        }
    
        /**
         * 从令牌中获取数据声明
         *
         * @param token 令牌
         * @return 数据声明
         */
        private static Claims getClaimsFromToken(String token) {
            Claims claims;
            try {
                claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
            } catch (Exception e) {
                claims = null;
            }
            return claims;
        }
    
        /**
         * 验证令牌
         * @param token
         * @param username
         * @return
         */
        public static Boolean validateToken(String token, String username) {
            String userName = getUsernameFromToken(token);
            return (userName.equals(username) && !isTokenExpired(token));
        }
    
        /**
         * 刷新令牌
         * @param token
         * @return
         */
        public static String refreshToken(String token) {
            String refreshedToken;
            try {
                Claims claims = getClaimsFromToken(token);
                claims.put(CREATED, new Date());
                refreshedToken = generateToken(claims);
            } catch (Exception e) {
                refreshedToken = null;
            }
            return refreshedToken;
        }
    
        /**
         * 判断令牌是否过期
         *
         * @param token 令牌
         * @return 是否过期
         */
        public static Boolean isTokenExpired(String token) {
            try {
                Claims claims = getClaimsFromToken(token);
                Date expiration = claims.getExpiration();
                return expiration.before(new Date());
            } catch (Exception e) {
                return false;
            }
        }
    
        /**
         * 获取请求token
         * @param request
         * @return
         */
        public static String getToken(HttpServletRequest request) {
            String token = request.getHeader("Authorization");
            String tokenHead = "Bearer ";
            if(token == null) {
                token = request.getHeader("token");
            } else if(token.contains(tokenHead)){
                token = token.substring(tokenHead.length());
            } 
            if("".equals(token)) {
                token = null;
            }
            return token;
        }
    
    }
    package com.louis.mango.admin.vo;
    
    /**
     * 登录接口封装对象
     * @author Louis
     * @date Oct 29, 2018
     */
    public class LoginBean {
    
        private String account;
        private String password;
        private String captcha;
        
        public String getAccount() {
            return account;
        }
        public void setAccount(String account) {
            this.account = account;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getCaptcha() {
            return captcha;
        }
        public void setCaptcha(String captcha) {
            this.captcha = captcha;
        }
        
    }

     

     

     

     

     

     

  • 相关阅读:
    Vue学录 (第三章)
    Vue学录 (第二章)
    Vue 学录 (第一章)
    SpringBoot 学集 (第七章) 数据访问
    Leetcode789 阻碍逃脱者 曼哈顿距离
    Leetcode707 设计链表 双向链表实现
    leetcode 743 网络延迟时间 Dijkstra算法
    Leetcode676 实现魔法字典
    Leetcode443 压缩字符串 双指针原地压缩算法
    Leetcode23 合并K个升序链表
  • 原文地址:https://www.cnblogs.com/tszr/p/15865863.html
Copyright © 2020-2023  润新知