SSO 单点登录实现方案
发布日期:2021-06-23 09:17:47 浏览次数:0 分类:技术文章

SSO 单点登录实现方案

基本概念

三种实现方案

Session 共享

Oauth 2.0 实现

JWT 实现单点登录

Spring Boot 实现 JWT

1.引入依赖

 <!--    引入JWT    -->        <dependency>            <groupId>com.auth0</groupId>            <artifactId>java-jwt</artifactId>            <version>3.10.3</version>        </dependency>

2.编写工具类

public class JwtUtils {
       // 用于JWT进行签名加密的秘钥    private static String SECRET = "code-duck-*%#@*!&";    /**     * JWT   包含三部分: Header 头部  Payload 负载 Signature 签名     * Signature: sign = hash(Base64(header) + Base64(payload)+secret)     * Header:     * {     * "alg": "HS256",     * "typ": "JWT"     * }     * payload:{     * <p>     * iss: jwt签发者     * sub: 面向的用户(jwt所面向的用户)     * aud: 接收jwt的一方     * exp: 过期时间戳(jwt的过期时间,这个过期时间必须要大于签发时间)     * nbf: 定义在什么时间之前,该jwt都是不可用的.     * iat: jwt的签发时间     * jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。     * <p>     * }     *     * @param map     * @return: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTM1NzcxNDAsInVzZXIiOiLnlKjmiLfkv6Hmga8ifQ.yDa69wPKNpDFMAPAnXBh-21rRXb5VvFdOqZcC0uDsQU     * @exception:     */    public static String generateToken(Map<String, String> map) {
           JWTCreator.Builder builder = JWT.create();        //Map 内的信息放到JWT payload 中        map.forEach((k, v) -> {
               builder.withClaim(k, v);        });        // 设置JWT 令牌 过期时间60s        Calendar installCalendar = Calendar.getInstance();        installCalendar.add(Calendar.SECOND, 60);        builder.withExpiresAt(installCalendar.getTime());        // 设置 签名 并返回token        return builder.sign(Algorithm.HMAC256(SECRET));    }    /**     * @Param: 传入token     * @return:     */    public static void verify(String token) {
           JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);    }    /**     * @Param: 传入token     * @return: 解密的token信息     */    public static DecodedJWT getTokenInfo(String token) {
           return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);    }}

3.获取 token

@RestController@RequestMapping("/user")public class UserController {
       @PostMapping("/login")    public Map<String, String> login() {
           HashMap<String, String> result = new HashMap<>();        // 获取用户信息        HashMap<String, String> map = new HashMap<>();        map.put("user", "用户信息");        // 生成 token        String token = JwtUtils.generateToken(map);        result.put("token", token);        return result;    }    @PostMapping("/test")    public void test() {
           System.out.println("测试方法");    }}

4.编写过滤器

public class JwtFilter implements Filter {
       @Override    public void init(FilterConfig filterConfig) throws ServletException {
       }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
           String token = ((HttpServletRequest) request).getHeader("token");        HashMap<String, String> map = new HashMap<>();        try {
               JwtUtils.verify(token);//验证令牌            chain.doFilter(request, response);        } catch (SignatureVerificationException e) {
               e.printStackTrace();            map.put("msg", "无效签名!");        } catch (TokenExpiredException e) {
               e.printStackTrace();            map.put("msg", "token过期!");        } catch (AlgorithmMismatchException e) {
               e.printStackTrace();            map.put("msg", "token算法不一致!");        } catch (Exception e) {
               e.printStackTrace();            map.put("msg", "token无效!!");        }        response.setContentType("application/json;charset=UTF-8");        response.getWriter().println(map);    }    @Override    public void destroy() {
       }}

5.注册过滤器

@Configurationpublic class FilterConfiguration {
       private String skipUrlPattern = "";    @Bean    public FilterRegistrationBean filterRegistration() {
           FilterRegistrationBean registration = new FilterRegistrationBean();        registration.setFilter(new JwtFilter());        registration.addInitParameter("skipUrlPattern", skipUrlPattern);        registration.addUrlPatterns("/*");        return registration;    }}
上一篇:Docker 部署 Elasticsearch
下一篇:安装火绒的情况下怎么关闭防火墙