springcloud-sso单点登陆(二)

单点登陆的实现方式有多种:
1、基于cas来做
2、spring cloud oauth2的spring全家桶
3、自定义jwt(不推荐)
下面我们基于spring全家桶来做一个单点登陆系统2019年12月23日最新springboot版本2.2.2.RELEASE;由于篇幅问题,我们分成两篇文章。
基于上一篇https://www.jianshu.com/p/80b125ea8e76
源码:https://github.com/xcocean/spring-cloud-sso

一、创建用户客户端

创建一个在根目录下创建business-user文件夹,在business-user下创建pom.xml:



    4.0.0
    
        com.qbccn
        parent
        0.0.1-SNAPSHOT
    

    com.qbccn
    business-user
    用户中心

    
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        

        
        
            org.springframework.cloud
            spring-cloud-starter-oauth2
        
        

        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
        
        
            com.zaxxer
            HikariCP
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
            
                
                
                    org.apache.tomcat
                    tomcat-jdbc
                
            
        
        
            mysql
            mysql-connector-java
        

        
            com.squareup.okhttp3
            okhttp
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    com.qbccn.UseApplication
                
            
        
    


关键配置如下:

package com.qbccn.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class UserResourceConfiguration extends ResourceServerConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .exceptionHandling()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //需要授权的路径
                .antMatchers("/user/**").hasAnyRole("USER")
                .antMatchers("/admin/**").hasAnyRole("ADMIN")
                .anyRequest().permitAll(); //其他页面所有人能访问
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // 配置资源 ID --对应sso的资源id
        resources.resourceId("backend-resources");
    }
}

application.yml,由于sso服务使用了8080端口,这里改成8081端口

server:
  port:8081
spring:
  main:
    allow-bean-definition-overriding: true
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/sso?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 123456
    hikari:
      minimum-idle: 1
      idle-timeout: 600000
      maximum-pool-size: 10
      auto-commit: true
      pool-name: MyHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
      connection-test-query: SELECT 1

security:
  oauth2:
    client:
      client-id: client
      client-secret: secret
      access-token-uri: http://localhost:8080/oauth/token
      user-authorization-uri: http://localhost:8080/oauth/authorize
    resource:
      token-info-uri: http://localhost:8080/oauth/check_token
mybatis:
  mapper-locations: classpath:mapper/*.xml

项目截图如下:


image.png

二、测试

启动项目后:浏览器访问http://localhost:8081/user/info/lk

image.png

我们用postman登陆拿到token:
image.png

带上token访问:http://localhost:8081/user/info/lk?access_token=fd3a7ca5-af58-48e7-8351-bc3272109189
image.png

lk这个用户没有admin权限,我们访问admin看看
image.png

可以看到我们被拒绝访问。用postman登陆admin获取token再访问:
image.png

http://localhost:8081/admin/userList?access_token=d5e43187-026e-4bb7-8af7-dade7b657f47
image.png

我们停止认证服务器再请求会报错,其中引入okhttp是打算从business-user做登陆的。
关于如何在oauth2 client拿到sso的用户登录信息,比如权限、角色、账号呀?在客户端直接调用即可,他会根据你请求的token去sso获取相关信息,我们不需要输入账号:

//拿用户名,类似普通项目的session get(username)
SecurityContextHolder.getContext().getAuthentication().getName();

前后端分离就是基于此完成,实际的场景并没有这么简单,有很多开发规范需要遵守。但是核心验证仍是这样,喜欢就点个赞吧_

你可能感兴趣的:(springcloud-sso单点登陆(二))