OAuth2实现单点登录SSO完整教程,其实不难!(下)

简介: OAuth2实现单点登录SSO完整教程,其实不难!

两个客户端

5.1. Maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cjs.sso</groupId>
    <artifactId>oauth2-sso-client-member</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>oauth2-sso-client-member</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.2. application.yml

server:
  port: 8082
  servlet:
    context-path: /memberSystem
security:
  oauth2:
    client:
      client-id: UserManagement
      client-secret: user123
      access-token-uri: http://localhost:8080/oauth/token
      user-authorization-uri: http://localhost:8080/oauth/authorize
    resource:
      jwt:
        key-uri: http://localhost:8080/oauth/token_key

image.png这里context-path不要设成/,不然重定向获取code的时候回被拦截

5.3. WebSecurityConfig

package com.cjs.example.config;
import com.cjs.example.util.EnvironmentUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
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;
/**
 * @author ChengJianSheng
 * @date 2019-03-03
 */
@EnableOAuth2Sso
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private EnvironmentUtils environmentUtils;
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/bootstrap/**");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if ("local".equals(environmentUtils.getActiveProfile())) {
            http.authorizeRequests().anyRequest().permitAll();
        }else {
            http.logout().logoutSuccessUrl("http://localhost:8080/logout")
                    .and()
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .csrf().disable();
        }
    }
}

说明:

  1. 最重要的注解是@EnableOAuth2Sso
  2. 权限控制这里采用Spring Security方法级别的访问控制,结合Thymeleaf可以很容易做权限控制
  3. 顺便多提一句,如果是前后端分离的话,前端需求加载用户的权限,然后判断应该显示那些按钮那些菜单

5.4. MemberController

package com.cjs.example.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.security.Principal;
/**
 * @author ChengJianSheng
 * @date 2019-03-03
 */
@Controller
@RequestMapping("/member")
public class MemberController {
    @GetMapping("/list")
    public String list() {
        return "member/list";
    }
    @GetMapping("/info")
    @ResponseBody
    public Principal info(Principal principal) {
        return principal;
    }
    @GetMapping("/me")
    @ResponseBody
    public Authentication me(Authentication authentication) {
        return authentication;
    }
    @PreAuthorize("hasAuthority('member:save')")
    @ResponseBody
    @PostMapping("/add")
    public String add() {
        return "add";
    }
    @PreAuthorize("hasAuthority('member:detail')")
    @ResponseBody
    @GetMapping("/detail")
    public String detail() {
        return "detail";
    }
}

5.5. Order项目跟它是一样的

server:
  port: 8083
  servlet:
    context-path: /orderSystem
security:
  oauth2:
    client:
      client-id: OrderManagement
      client-secret: order123
      access-token-uri: http://localhost:8080/oauth/token
      user-authorization-uri: http://localhost:8080/oauth/authorize
    resource:
      jwt:
        key-uri: http://localhost:8080/oauth/token_key

5.6. 关于退出

退出就是清空用于与SSO客户端建立的所有的会话,简单的来说就是使所有端点的Session失效,如果想做得更好的话可以令Token失效,但是由于我们用的JWT,故而撤销Token就不是那么容易,关于这一点,在官网上也有提到:

image.png

本例中采用的方式是在退出的时候先退出业务服务器,成功以后再回调认证服务器,但是这样有一个问题,就是需要主动依次调用各个业务服务器的logout

工程结构

image.png

附上源码:https://github.com/chengjiansheng/cjs-oauth2-sso-demo.git

目录
相关文章
|
存储 安全 Java
OAuth2实现单点登录SSO完整教程,其实不难!(上)
OAuth2实现单点登录SSO完整教程,其实不难!
3532 1
OAuth2实现单点登录SSO完整教程,其实不难!(上)
|
4月前
|
存储 安全 数据安全/隐私保护
SSO 单点登录与 OAuth2.0 的技术区别与应用
【8月更文挑战第24天】在现代软件开发和企业信息化建设中,身份认证与授权是不可或缺的一环。SSO(Single Sign-On,单点登录)和OAuth 2.0作为两种重要的身份认证与授权机制,各自具有独特的特点和应用场景。本文将详细探讨这两种机制的区别,并分享在工作学习中的技术干货。
200 0
|
7月前
|
安全 数据安全/隐私保护 UED
单点登录原理
单点登录原理
109 3
|
7月前
|
安全 数据安全/隐私保护 UED
|
安全 数据安全/隐私保护
单点登录(SSO)看这一篇就够了
单点登录(SSO)看这一篇就够了
1110 4
|
消息中间件 前端开发 JavaScript
SSO 单点登录和 OAuth2.0 的区别和理解
SSO 单点登录和 OAuth2.0 的区别和理解
|
安全 数据安全/隐私保护 UED
什么是单点登录(SSO)?底层原理是什么?
什么是单点登录(SSO)?底层原理是什么?
458 0
|
存储 NoSQL 算法
搞懂单点登录SSO,基于SpringBoot+JWT实现单点登录解决方案
单点登录是目前比较流行的企业业务整合的解决方案之一。单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。例如:百度旗下有很多的产品,比如百度贴吧、百度知道、百度文库等,只要登录百度账号,在任何一个地方都是已登录状态,不需要重新登录。 单点登录是互联网应用和企业级平台中的基础组件服务。接下来就介绍单点登录的原理,并基于SpringBoot +JWT实现单点登录解决方案。
14082 2
搞懂单点登录SSO,基于SpringBoot+JWT实现单点登录解决方案
OAuth2实现单点登录SSO完整教程,其实不难!(中)
OAuth2实现单点登录SSO完整教程,其实不难!
497 1
OAuth2实现单点登录SSO完整教程,其实不难!(中)