SpringBoot实战电商项目mall(20k+star)地址: https://github.com/macrozheng/mall
Spring Cloud Security 为构建安全的SpringBoot应用提供了一系列解决方案,结合Oauth2能够实现单点登陆功能,本文将对其单点登陆用法进行详细介绍。java
单点登陆(Single Sign On)指的是当有多个系统须要登陆时,用户只需登陆一个系统,就能够访问其余须要登陆的系统而无需登陆。git
这里咱们建立一个oauth2-client服务做为须要登陆的客户端服务,使用上一节中的oauth2-jwt-server服务做为认证服务,当咱们在oauth2-jwt-server服务上登陆之后,就能够直接访问oauth2-client须要登陆的接口,来演示下单点登陆功能。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
server: port: 9501 servlet: session: cookie: name: OAUTH2-CLIENT-SESSIONID #防止Cookie冲突,冲突会致使登陆验证不经过 oauth2-server-url: http://localhost:9401 spring: application: name: oauth2-client security: oauth2: #与oauth2-server对应的配置 client: client-id: admin client-secret: admin123456 user-authorization-uri: ${oauth2-server-url}/oauth/authorize access-token-uri: ${oauth2-server-url}/oauth/token resource: jwt: key-uri: ${oauth2-server-url}/oauth/token_key
@EnableOAuth2Sso @SpringBootApplication public class Oauth2ClientApplication { public static void main(String[] args) { SpringApplication.run(Oauth2ClientApplication.class, args); } }
/** * Created by macro on 2019/9/30. */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/getCurrentUser") public Object getCurrentUser(Authentication authentication) { return authentication; } }
修改oauth2-jwt-server模块中的AuthorizationServerConfig类,将绑定的跳转路径为http://localhost:9501/login,并添加获取秘钥时的身份认证。github
/** * 认证服务器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { //以上省略一堆代码... @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("admin") .secret(passwordEncoder.encode("admin123456")) .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(864000) // .redirectUris("http://www.baidu.com") .redirectUris("http://localhost:9501/login") //单点登陆时配置 .scopes("all") .authorizedGrantTypes("authorization_code","password","refresh_token"); } @Override public void configure(AuthorizationServerSecurityConfigurer security) { security.tokenKeyAccess("isAuthenticated()"); // 获取密钥须要身份认证,使用单点登陆时必须配置 } }
autoApprove(true)
配置:/** * 认证服务器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { //以上省略一堆代码... @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("admin") .secret(passwordEncoder.encode("admin123456")) .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(864000) // .redirectUris("http://www.baidu.com") .redirectUris("http://localhost:9501/login") //单点登陆时配置 .autoApprove(true) //自动受权配置 .scopes("all") .authorizedGrantTypes("authorization_code","password","refresh_token"); } }
这里咱们使用Postman来演示下如何使用正确的方式调用须要登陆的客户端接口。
{ "authorities": [ { "authority": "admin" } ], "details": { "remoteAddress": "0:0:0:0:0:0:0:1", "sessionId": "63BB793E35383B2FFC608333B3BF4988", "tokenValue": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJtYWNybyIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE1NzI2OTAxNzUsImF1dGhvcml0aWVzIjpbImFkbWluIl0sImp0aSI6IjIwN2U5MTQzLTVjNTUtNDhkMS1iZmU3LTgwMzUyZTQ3Y2QyZCIsImNsaWVudF9pZCI6ImFkbWluIiwiZW5oYW5jZSI6ImVuaGFuY2UgaW5mbyJ9.xf3cBu9yCm0sME0j3UcP53FwF4tJVJC5aJbEj_Y2XcU", "tokenType": "bearer", "decodedDetails": null }, "authenticated": true, "userAuthentication": { "authorities": [ { "authority": "admin" } ], "details": null, "authenticated": true, "principal": "macro", "credentials": "N/A", "name": "macro" }, "clientOnly": false, "oauth2Request": { "clientId": "admin", "scope": [ "all" ], "requestParameters": { "client_id": "admin" }, "resourceIds": [], "authorities": [], "approved": true, "refresh": false, "redirectUri": null, "responseTypes": [], "extensions": {}, "grantType": null, "refreshTokenRequest": null }, "principal": "macro", "credentials": "", "name": "macro" }
/** * 在接口上配置权限时使用 * Created by macro on 2019/10/11. */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(101) public class SecurityConfig extends WebSecurityConfigurerAdapter { }
/** * Created by macro on 2019/9/30. */ @RestController @RequestMapping("/user") public class UserController { @PreAuthorize("hasAuthority('admin')") @GetMapping("/auth/admin") public Object adminAuth() { return "Has admin auth!"; } }
admin
权限的账号,好比andy:123456
获取令牌后访问该接口,会发现没有权限访问。springcloud-learning ├── oauth2-jwt-server -- 使用jwt的oauth2认证测试服务 └── oauth2-client -- 单点登陆的oauth2客户端服务
https://github.com/macrozheng/springcloud-learningweb
mall项目全套学习教程连载中,关注公众号第一时间获取。spring