赞
踩
oauth2 定义了下面四种授权方式:
* response_type:表示授权类型,必选项,此处的值固定为"code"
* client_id:表示客户端的ID,必选项
* redirect_uri:表示重定向URI,可选项
* scope:表示申请的权限范围,可选项
* state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
上代码:
- package com.oath.config;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.http.HttpMethod;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
- import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
-
- @Configuration
- @EnableAuthorizationServer
- public class OAuth2ServerConfig extends AuthorizationServerConfigurerAdapter {
-
- @Autowired
- private AuthenticationManager authenticationManager;
-
- @Autowired
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Autowired
- private UserDetailsService userDetailsService;
-
- @Override
- public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
- oauthServer.realm("oauth2-resources") // code授权添加
- .tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()") // allow check token
- .allowFormAuthenticationForClients();
- }
-
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- endpoints.authenticationManager(authenticationManager)
- // 允许 GET、POST 请求获取 token,即访问端点:oauth/token
- .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
- // 要使用refresh_token的话,需要额外配置userDetailsService
- endpoints.userDetailsService(userDetailsService);
- }
-
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
- clients.inMemory().withClient("demoApp").secret(bCryptPasswordEncoder.encode("demoAppSecret"))
- .redirectUris("http://baidu.com")// code授权添加
- .authorizedGrantTypes("authorization_code", "client_credentials", "password", "refresh_token")
- .scopes("all").resourceIds("oauth2-resource").accessTokenValiditySeconds(1200)
- .refreshTokenValiditySeconds(50000);
- }
-
- }
资源服务器:
- package com.oath.config;
-
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
- import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
-
- @Configuration
- @EnableResourceServer
- public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.requestMatchers().antMatchers("/api/**").and().authorizeRequests().antMatchers("/api/**").authenticated();
- }
- }
安全配置:
- package com.oath.config;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.core.userdetails.User;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.provisioning.InMemoryUserDetailsManager;
-
- @EnableGlobalMethodSecurity(prePostEnabled = true)
- @EnableWebSecurity
- public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
-
- @Bean
- public BCryptPasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- /**
- * anyRequest | 匹配所有请求路径
- * access | SpringEl表达式结果为true时可以访问
- * anonymous | 匿名可以访问
- * denyAll | 用户不能访问
- * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
- * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
- * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
- * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
- * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
- * hasRole | 如果有参数,参数表示角色,则其角色可以访问
- * permitAll | 用户可以任意访问
- * rememberMe | 允许通过remember-me登录的用户访问
- * authenticated | 用户登录后可访问
- */
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.csrf().disable();
- http.requestMatchers().antMatchers("/oauth/**", "/login/**", "/logout/**").and().authorizeRequests()
- .antMatchers("/oauth/**").authenticated().and().formLogin().permitAll();
- }
-
- // 配置内存模式的用户
- @Bean
- @Override
- protected UserDetailsService userDetailsService() {
- InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
- manager.createUser(User.withUsername("demoUser1").password(this.passwordEncoder().encode("123456"))
- .authorities("USER").build());
- manager.createUser(User.withUsername("demoUser2").password(this.passwordEncoder().encode("123456"))
- .authorities("USER").build());
- return manager;
- }
-
- @Override
- @Bean
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
- }
- }
测试接口:
- package com.oath.controller;
-
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- @RestController
- @RequestMapping("/api")
- public class HelloOath2Controller {
- @RequestMapping("/hello/{id}")
- public String helloOath2(@PathVariable long id) {
- System.out.println("请求的ID编码为:" + id);
- return "helloOath2";
- }
- }
启动类:
- package com.oath;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- @SpringBootApplication
- public class SpingbootOath2DemoApplication {
-
- /**
- * *【密码授权模式-client】
- * 密码模式需要参数:username,password,grant_type,client_id,client_secret
- * http://localhost:8080/oauth/token?username=demoUser1&password=123456&grant_type=password&client_id=demoApp&client_secret=demoAppSecret
- *
- * *【客户端授权模式-password】 客户端模式需要参数:grant_type,client_id,client_secret
- * http://localhost:8080/oauth/token?grant_type=client_credentials&client_id=demoApp&client_secret=demoAppSecret
- *
- * *【授权码模式-code】 获取code
- * http://localhost:8080/oauth/authorize?response_type=code&client_id=demoApp&redirect_uri=http://baidu.com
- *
- ** 【通过code】 换token
- * http://localhost:8080/oauth/token?grant_type=authorization_code&code=Filepd&client_id=demoApp&client_secret=demoAppSecret&redirect_uri=http://baidu.com
- * 这里的code字段是授权码模式中返回的code 例如: https://www.baidu.com/?code=tsuHSh
- *
- ** 【通过refresh token】 刷新token
- * http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=7ba47059-d853-4050-9c64-69d0cade71a7&client_id=demoApp&client_secret=demoAppSecret
- * 其中grant_type为固定值:grant_type=refresh_token , refresh_token = 通过code获取的token中的refresh_token
- *
- */
-
- public static void main(String[] args) {
- SpringApplication.run(SpingbootOath2DemoApplication.class, args);
- }
-
- }
POM依赖
- <?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.4.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.oath.demo</groupId>
- <artifactId>spingboot-oath2-demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>spingboot-oath2-demo</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-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.security.oauth</groupId>
- <artifactId>spring-security-oauth2</artifactId>
- <version>2.3.5.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </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>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
测试:
【密码授权模式-client】 密码模式需要参数:username,password,grant_type,client_id,client_secret http://localhost:8080/oauth/token?username=demoUser1&password=123456&grant_type=password&client_id=demoApp&client_secret=demoAppSecret 【客户端授权模式-password】 客户端模式需要参数:grant_type,client_id,client_secret http://localhost:8080/oauth/token?grant_type=client_credentials&client_id=demoApp&client_secret=demoAppSecret 【授权码模式-code】 获取code http://localhost:8080/oauth/authorize?response_type=code&client_id=demoApp&redirect_uri=http://baidu.com 通过code换token(注意:code参数为授权码模式返回的参数) http://localhost:8080/oauth/token?grant_type=authorization_code&code=Filepd&client_id=demoApp&client_secret=demoAppSecret&redirect_uri=http://baidu.com 【通过refresh token】 刷新token http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=7ba47059-d853-4050-9c64-69d0cade71a7&client_id=demoApp&client_secret=demoAppSecret 其中grant_type为固定值:grant_type=refresh_token , refresh_token = 通过code获取的token中的refresh_token
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。