spring oauth2
- AngularJS+Spring Security使用基本认证
- Secure Spring REST API使用基本验证
OAuth2是什么?
OAuth 2.0授权框架使第三方应用程序来获取对HTTP服务的有限访问机会。无论是通过编排资源所有者和HTTP服务之间的交互批准的资源所有者,或通过允许第三方应用程序来获取自己的访问权限。
Spring Security OAuth项目提供所有可能开发使用的Spring OAuth2用户兼容实现所需的API。 Official Spring security oauth项目提供了实现 OAuth2 一个完整的例子。这个篇文章的代码示例是在这个官方提供的例子的基础上修改。这篇文章的目的是只使用所需最低限度的功能,以演示我们的REST API,仅此而已。我也还在学习,所以如果有什么不对的地方随时纠正我。
1. OAuth2角色
- 资源拥有乾(resource owner):
能够准许访问受保护资源的实体。当资源的所有者是一个人,它被称为终端用户。
- 资源服务器(resource server):
服务器托管受保护的资源,能够接受和响应使用访问令牌保护资源的请求。
- 客户端(client):
应用程序使资源所有者的请求有授权访问受保护资源。这可能是一个移动应用程序要求您的权限来访问您的Facebook订阅源,REST客户端试图访问REST API,如一个网站[Stackoverflow]提供使用Facebook帐户或是类似QQ第三方帐号登录来替代使用网站帐号登录。
- authorization server:
服务器在成功认证资源所有者和获得授权之后发出访问令牌给客户端。
- 授权码
- 隐性的
- 资源所有者密码凭据
- 客户端凭据
我们将使用资源所有者密码凭据授予类型。原因很简单,我们没有执行那些重定向到一个登录页面视图。
- Access Token : 发送的每个请求,有效期一般是一个很短的寿命[例如:一个小时]
- Refresh Token : 主要用于获取新的访问令牌,而不是每个请求都发送,通常比访问令牌生命更长。
资源服务器承载资源[REST API],客户端感兴趣的资源位于 /user/ 。@EnableResourceServer注释,适用在OAuth2资源服务器,实现了Spring Security的过滤器验证的请求传入OAuth2令牌。 ResourceServerConfigurerAdapter类实现 ResourceServerConfigurer 提供的方法来调整 OAuth2安全保护的访问规则和路径。
package com.yiibai.springmvc.security;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; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;@Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {private static final String RESOURCE_ID = "my_rest_api";@Overridepublic void configure(ResourceServerSecurityConfigurer resources) {resources.resourceId(RESOURCE_ID).stateless(false);}@Overridepublic void configure(HttpSecurity http) throws Exception {http.anonymous().disable().requestMatchers().antMatchers("/user/**").and().authorizeRequests().antMatchers("/user/**").access("hasRole('ADMIN')").and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());}}
package com.yiibai.springmvc.security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; 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; import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.security.oauth2.provider.token.TokenStore;@Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {private static String REALM="MY_OAUTH_REALM";@Autowiredprivate TokenStore tokenStore;@Autowiredprivate UserApprovalHandler userApprovalHandler;@Autowired@Qualifier("authenticationManagerBean")private AuthenticationManager authenticationManager;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient("my-trusted-client").authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit").authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT").scopes("read", "write", "trust").secret("secret").accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler).authenticationManager(authenticationManager);}@Overridepublic void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {oauthServer.realm(REALM+"/client");}}
上面的配置:
- 注册一个客户端,客户端ID是“my-trusted-client'和密码为'secret',客户端允许的角色和范围;
- 指定任何生成的访问令牌的有效期只有120秒;
- 指定任何刷新生成令牌的有效期只有600秒
package com.yiibai.springmvc.security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;@Configuration @EnableWebSecurity public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {@Autowiredprivate ClientDetailsService clientDetailsService;@Autowiredpublic void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("bill").password("abc123").roles("ADMIN").and().withUser("bob").password("abc123").roles("USER");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().anonymous().disable().authorizeRequests().antMatchers("/oauth/token").permitAll();}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Beanpublic TokenStore tokenStore() {return new InMemoryTokenStore();}@Bean@Autowiredpublic TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();handler.setTokenStore(tokenStore);handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));handler.setClientDetailsService(clientDetailsService);return handler;}@Bean@Autowiredpublic ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {TokenApprovalStore store = new TokenApprovalStore();store.setTokenStore(tokenStore);return store;}}
package com.yiibai.springmvc.security;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {@Autowiredprivate OAuth2SecurityConfiguration securityConfig;@Overrideprotected MethodSecurityExpressionHandler createExpressionHandler() {return new OAuth2MethodSecurityExpressionHandler();} }
- 试图访问资源[REST API],但是这是在没有任何授权[失败]情况下。
GET http://localhost:8080/SpringSecurityOAuth2Example/user/
- 要求令牌[访问+刷新]使用HTTP POST 在 /oauth/token 上 ,grant_type=password和资源所有者凭证作为 req-params 。此外在授权头发送客户端凭据。
POST http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123
- 要求通过有效的刷新令牌新的访问令牌,在 /oauth/token 上使用HTTP POST,以及 grant_type=refresh_token 一并发送刷新令牌。此外在授权头发送客户端凭据。
POST http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=refresh_token&refresh_token=094b7d23-973f-4cc1-83ad-8ffd43de1845
- 使用 access_token 查询参数和要求提供访问资源的令牌。
GET http://localhost:8080/SpringSecurityOAuth2Example/user/?access_token=3525d0e4-d881-49e7-9f91-bcfd18259109
5. Rest API
package com.yiibai.springmvc.controller;import java.util.List;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder;import com.yiibai.springmvc.model.User; import com.yiibai.springmvc.service.UserService;@RestController public class HelloWorldRestController {@AutowiredUserService userService; //Service which will do all data retrieval/manipulation work//-------------------Retrieve All Users--------------------------------------------------------@RequestMapping(value = "/user/", method = RequestMethod.GET)public ResponseEntity<List<User>> listAllUsers() {List<User> users = userService.findAllUsers();if(users.isEmpty()){return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND}return new ResponseEntity<List<User>>(users, HttpStatus.OK);}//-------------------Retrieve Single User--------------------------------------------------------@RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE,MediaType.APPLICATION_XML_VALUE})public ResponseEntity<User> getUser(@PathVariable("id") long id) {System.out.println("Fetching User with id " + id);User user = userService.findById(id);if (user == null) {System.out.println("User with id " + id + " not found");return new ResponseEntity<User>(HttpStatus.NOT_FOUND);}return new ResponseEntity<User>(user, HttpStatus.OK);}//-------------------Create a User--------------------------------------------------------@RequestMapping(value = "/user/", method = RequestMethod.POST)public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) {System.out.println("Creating User " + user.getName());if (userService.isUserExist(user)) {System.out.println("A User with name " + user.getName() + " already exist");return new ResponseEntity<Void>(HttpStatus.CONFLICT);}userService.saveUser(user);HttpHeaders headers = new HttpHeaders();headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());return new ResponseEntity<Void>(headers, HttpStatus.CREATED);}//------------------- Update a User --------------------------------------------------------@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)public ResponseEntity<User> updateUser(@PathVariable("id") long id, @RequestBody User user) {System.out.println("Updating User " + id);User currentUser = userService.findById(id);if (currentUser==null) {System.out.println("User with id " + id + " not found");return new ResponseEntity<User>(HttpStatus.NOT_FOUND);}currentUser.setName(user.getName());currentUser.setAge(user.getAge());currentUser.setSalary(user.getSalary());userService.updateUser(currentUser);return new ResponseEntity<User>(currentUser, HttpStatus.OK);}//------------------- Delete a User --------------------------------------------------------@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)public ResponseEntity<User> deleteUser(@PathVariable("id") long id) {System.out.println("Fetching & Deleting User with id " + id);User user = userService.findById(id);if (user == null) {System.out.println("Unable to delete. User with id " + id + " not found");return new ResponseEntity<User>(HttpStatus.NOT_FOUND);}userService.deleteUserById(id);return new ResponseEntity<User>(HttpStatus.NO_CONTENT);}//------------------- Delete All Users --------------------------------------------------------@RequestMapping(value = "/user/", method = RequestMethod.DELETE)public ResponseEntity<User> deleteAllUsers() {System.out.println("Deleting All Users");userService.deleteAllUsers();return new ResponseEntity<User>(HttpStatus.NO_CONTENT);}}
客户端1: Postman
现在我们获取头。选择HTTP方法为 POST,Authorization Type:Basic Auth ,URL:http://localhost:8080/SpringSecurityOAuth2/oauth/token?grant_type=password&username=bill&password=abc123 ,然后再将客户端凭据 [my-trusted-client/secret]添加到授权头。点击"update request"(更新请求),发送POST请求后,您会在响应中收到访问令牌(access-token),以及刷新令牌(refresh-token)。如下所示 -
保存这些令牌在需要它们时。现在可以使用这个访问令牌[有效期为2分钟]来访问资源。现在我们再使用这个 token 来访问资源,把它添加到URL中如:http://localhost:8080/SpringSecurityOAuth2/user/?access_token=7fbb77ae-3d8f-4d78-b8de-3222353f680b 得到结果如下所示 -
我们需要一个新的访问令牌。触发一个 post 以后用刷新令牌来获得一个新的访问令牌。请求URL:http://localhost:8080/SpringSecurityOAuth2/oauth/token?grant_type=refresh_token&refresh_token=fefcf12c-2683-4f1a-a446-941666dcfe23
使用这个新的访问令牌(c8edfa2f-d2aa-4f1b-81e1-32df3fefe9a8)继续访问资源。把它添加到URL中如:http://localhost:8080/SpringSecurityOAuth2/user/?access_token=be5c7dec-ae17-403d-ab66-86cf5262f159 得到结果如下所示 -
package com.yiibai.springmvc;import java.net.URI; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List;import org.apache.commons.codec.binary.Base64; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate;import com.yiibai.springmvc.model.AuthTokenInfo; import com.yiibai.springmvc.model.User;public class SpringRestClient {public static final String REST_SERVICE_URI = "http://localhost:8080/SpringSecurityOAuth2";public static final String AUTH_SERVER_URI = "http://localhost:8080/SpringSecurityOAuth2/oauth/token";public static final String QPM_PASSWORD_GRANT = "?grant_type=password&username=bill&password=abc123";public static final String QPM_ACCESS_TOKEN = "?access_token=";/** Prepare HTTP Headers.*/private static HttpHeaders getHeaders(){HttpHeaders headers = new HttpHeaders();headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));return headers;}/** Add HTTP Authorization header, using Basic-Authentication to send client-credentials.*/private static HttpHeaders getHeadersWithClientCredentials(){String plainClientCredentials="my-trusted-client:secret";String base64ClientCredentials = new String(Base64.encodeBase64(plainClientCredentials.getBytes()));HttpHeaders headers = getHeaders();headers.add("Authorization", "Basic " + base64ClientCredentials);return headers;} /** Send a POST request [on /oauth/token] to get an access-token, which will then be send with each request.*/@SuppressWarnings({ "unchecked"})private static AuthTokenInfo sendTokenRequest(){RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> request = new HttpEntity<String>(getHeadersWithClientCredentials());ResponseEntity<Object> response = restTemplate.exchange(AUTH_SERVER_URI+QPM_PASSWORD_GRANT, HttpMethod.POST, request, Object.class);LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>)response.getBody();AuthTokenInfo tokenInfo = null;if(map!=null){tokenInfo = new AuthTokenInfo();tokenInfo.setAccess_token((String)map.get("access_token"));tokenInfo.setToken_type((String)map.get("token_type"));tokenInfo.setRefresh_token((String)map.get("refresh_token"));tokenInfo.setExpires_in((int)map.get("expires_in"));tokenInfo.setScope((String)map.get("scope"));System.out.println(tokenInfo);//System.out.println("access_token ="+map.get("access_token")+", token_type="+map.get("token_type")+", refresh_token="+map.get("refresh_token")//+", expires_in="+map.get("expires_in")+", scope="+map.get("scope"));;}else{System.out.println("No user exist----------");}return tokenInfo;}/** Send a GET request to get list of all users.*/@SuppressWarnings({ "unchecked", "rawtypes" })private static void listAllUsers(AuthTokenInfo tokenInfo){Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting listAllUsers API-----------");RestTemplate restTemplate = new RestTemplate(); HttpEntity<String> request = new HttpEntity<String>(getHeaders());ResponseEntity<List> response = restTemplate.exchange(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),HttpMethod.GET, request, List.class);List<LinkedHashMap<String, Object>> usersMap = (List<LinkedHashMap<String, Object>>)response.getBody();if(usersMap!=null){for(LinkedHashMap<String, Object> map : usersMap){System.out.println("User : id="+map.get("id")+", Name="+map.get("name")+", Age="+map.get("age")+", Salary="+map.get("salary"));;}}else{System.out.println("No user exist----------");}}/** Send a GET request to get a specific user.*/private static void getUser(AuthTokenInfo tokenInfo){Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting getUser API----------");RestTemplate restTemplate = new RestTemplate();HttpEntity<String> request = new HttpEntity<String>(getHeaders());ResponseEntity<User> response = restTemplate.exchange(REST_SERVICE_URI+"/user/1"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),HttpMethod.GET, request, User.class);User user = response.getBody();System.out.println(user);}/** Send a POST request to create a new user.*/private static void createUser(AuthTokenInfo tokenInfo) {Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting create User API----------");RestTemplate restTemplate = new RestTemplate();User user = new User(0,"Sarah",51,134);HttpEntity<Object> request = new HttpEntity<Object>(user, getHeaders());URI uri = restTemplate.postForLocation(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),request, User.class);System.out.println("Location : "+uri.toASCIIString());}/** Send a PUT request to update an existing user.*/private static void updateUser(AuthTokenInfo tokenInfo) {Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting update User API----------");RestTemplate restTemplate = new RestTemplate();User user = new User(1,"Tomy",33, 70000);HttpEntity<Object> request = new HttpEntity<Object>(user, getHeaders());ResponseEntity<User> response = restTemplate.exchange(REST_SERVICE_URI+"/user/1"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),HttpMethod.PUT, request, User.class);System.out.println(response.getBody());}/** Send a DELETE request to delete a specific user.*/private static void deleteUser(AuthTokenInfo tokenInfo) {Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting delete User API----------");RestTemplate restTemplate = new RestTemplate();HttpEntity<String> request = new HttpEntity<String>(getHeaders());restTemplate.exchange(REST_SERVICE_URI+"/user/3"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),HttpMethod.DELETE, request, User.class);}/** Send a DELETE request to delete all users.*/private static void deleteAllUsers(AuthTokenInfo tokenInfo) {Assert.notNull(tokenInfo, "Authenticate first please......");System.out.println("\nTesting all delete Users API----------");RestTemplate restTemplate = new RestTemplate();HttpEntity<String> request = new HttpEntity<String>(getHeaders());restTemplate.exchange(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),HttpMethod.DELETE, request, User.class);}public static void main(String args[]){AuthTokenInfo tokenInfo = sendTokenRequest();listAllUsers(tokenInfo);getUser(tokenInfo);createUser(tokenInfo);listAllUsers(tokenInfo);updateUser(tokenInfo);listAllUsers(tokenInfo);deleteUser(tokenInfo);listAllUsers(tokenInfo);deleteAllUsers(tokenInfo);listAllUsers(tokenInfo);} }
AuthTokenInfo [access_token=fceed386-5923-4bf8-b193-1d76f95da4c4, token_type=bearer, refresh_token=29d28ee2-9d09-483f-a2d6-7f93e7a31667, expires_in=71, scope=read write trust]Testing listAllUsers API----------- User : id=1, Name=Sam, Age=30, Salary=70000.0 User : id=2, Name=Tom, Age=40, Salary=50000.0 User : id=3, Name=Jerome, Age=45, Salary=30000.0 User : id=4, Name=Silvia, Age=50, Salary=40000.0Testing getUser API---------- User [id=1, name=Sam, age=30, salary=70000.0]Testing create User API---------- Location : http://localhost:8080/SpringSecurityOAuth2Example/user/5Testing listAllUsers API----------- User : id=1, Name=Sam, Age=30, Salary=70000.0 User : id=2, Name=Tom, Age=40, Salary=50000.0 User : id=3, Name=Jerome, Age=45, Salary=30000.0 User : id=4, Name=Silvia, Age=50, Salary=40000.0 User : id=5, Name=Sarah, Age=51, Salary=134.0Testing update User API---------- User [id=1, name=Tomy, age=33, salary=70000.0]Testing listAllUsers API----------- User : id=1, Name=Tomy, Age=33, Salary=70000.0 User : id=2, Name=Tom, Age=40, Salary=50000.0 User : id=3, Name=Jerome, Age=45, Salary=30000.0 User : id=4, Name=Silvia, Age=50, Salary=40000.0 User : id=5, Name=Sarah, Age=51, Salary=134.0Testing delete User API----------Testing listAllUsers API----------- User : id=1, Name=Tomy, Age=33, Salary=70000.0 User : id=2, Name=Tom, Age=40, Salary=50000.0 User : id=4, Name=Silvia, Age=50, Salary=40000.0 User : id=5, Name=Sarah, Age=51, Salary=134.0Testing all delete Users API----------Testing listAllUsers API----------- No user exist----------
工程目录结构
pom.xml
<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><groupId>com.yiibai.springmvc</groupId><artifactId>SpringSecurityOAuth2</artifactId><version>1.0.0</version><packaging>war</packaging><name>SpringSecurityOAuth2Example</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><springframework.version>4.3.1.RELEASE</springframework.version><springsecurity.version>4.1.1.RELEASE</springsecurity.version><springsecurityoauth2.version>2.0.10.RELEASE</springsecurityoauth2.version><jackson.library>2.7.5</jackson.library></properties><dependencies><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${springframework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springframework.version}</version></dependency><!-- Spring Security --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>${springsecurity.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>${springsecurity.version}</version></dependency><!-- Spring Security OAuth2--><dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>${springsecurityoauth2.version}</version></dependency><!-- Jackson libraries --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.library}</version></dependency><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>${jackson.library}</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.2</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.4</version><configuration><warSourceDirectory>src/main/webapp</warSourceDirectory><warName>SpringSecurityOAuth2</warName><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin></plugins><finalName>SpringSecurityOAuth2</finalName></build> </project>
下载源代码
参考
- OAuth2 规范
- Spring OAuth2 官方参考
- Spring Security 4 工程主页
- Spring Security 4 参考手册
spring oauth2相关推荐
- spring oauth2+JWT后端自动刷新access_token
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | Braska 来源 | cnblogs.com/br ...
- spring oauth2 的error_description本地提示中文,线上提示英文。
spring oauth2 的error_description本地提示中文,线上提示英文. 自由的灵魂需要一颗勇敢的心,要勇敢的自发去成全自己. 解决方案 在yml或properties文件中进行如 ...
- spring oauth2学习笔记
一 主要参考资料 https://echocow.cn/articles/2019/07/14/1563082088646.html 1.1 博客地址: echocow.cn[重点关注,对应的代码路径 ...
- spring oauth2 实现用户名密码登录、手机号验证码登录返回token
文章目录 介绍 实现功能 用户名密码登录 步骤 编写成功处理器 配置成功处理器 手机号验证码登录 步骤 重写SmsCodeAuthenticationSecurityConfig 测试 用户名密码登录 ...
- 带有JWT示例的Spring Oauth2
有时以前,我们发表了一篇文章,分享了一种在云环境中实现无状态会话的自定义方法. 今天,让我们探讨为Spring Boot应用程序设置Oauth2身份验证的另一个流行用例. 在此示例中,我们将使用JSO ...
- 芋道 spring security oauth2 入门_Spring官方宣布:新的Spring OAuth2.0授权服务器已经来了
1. 前言 记不记得之前发过一篇文章Spring 官方发起Spring Authorization Server 项目.该项目是由Spring Security主导的一个社区驱动的.独立的孵化项目.由 ...
- Spring OAuth2 授权服务器配置详解
前两篇文章分别体验了Spring Authorization Server的使用和讲解了其各个过滤器的作用.今天来讲讲Spring Authorization Server授权服务器的配置.强烈建议自 ...
- 实战讲解Spring Oauth2.0密码模式和授权码模式(内存inMemory+持久化jdbc配置)
1 缘起 先吐槽, 在搜索关于Oauth2.0授权码方式认证时, 遇到的问题比较多,一句话,按照其分享的步骤一步一步来,最终,无法成功, 本想,抄近路,看一些前人分享的应用案例,直接使用, 近路不通, ...
- spring oauth2 social实现QQ登录
文章目录 介绍 实现功能 开发步骤 开发流程图 引入jar包 数据库sql QQ用户信息实体类 QQapi 重写OAuth2Template 编写自己的QQServiceProvider 编写自己的Q ...
最新文章
- 2016-1-4作业
- 数据库事务隔离级别(转)
- spring ioc原理解析
- 番石榴的ListenableFuture
- 用C语言实现津巴布韦这道算法题?
- K8S精华问答 | 应用和运行时平台是怎样解耦的?
- Jeecg-Boot 快速开发平台,新手入门教程
- linux开发读取外部存储,Android 获取外接储存的设备路径(如挂载的U盘),android挂载...
- Shadow Mapping续
- matlab 浮动波动率,Matlab计算股票价格波动率
- 大数据Hadoop之——Cloudera Hadoop(CM 6.3.1+CDH 6.3.2环境部署)
- 一WAN多拨(一号多拨)实验
- 02. 禁止修改 IP 上网 ❀ 飞塔 (Fortinet5.4) 防火墙
- 通道注意力机制keras_在TensorFlow+Keras环境下使用RoI池化一步步实现注意力机制
- 苹果推iOS游戏手柄,掌上游戏主机格局变天?
- vue中实现Excel导入导出功能
- 【iOS沉思录】Objective-C语言消息传递机制三道防线:消息转发机制详解
- 药房管理系统源码 药房源码
- Fliqlo屏/保mac使用方法
- dbg-macro:C++代码调试小工具
热门文章
- LayaAir 2.12.2新版本已发布,即将进入3.0时代
- layaair发布html5,全面了解H5微信小游戏 LayaAir引擎支持一键发布
- 分类变量编码python处理
- 首次公开,阿里技术团队编写的“大厂面试参考指南”v1.0版本
- 做人,少记仇,多记好
- MDT 2013 从入门到精通之AD域环境准备
- Linux命令之dhclient,Linux中dhclient命令起什么作用呢?
- php后门绕过eval关键字,一些变态的PHP一句话后门收集
- 利用cmd执行adb(os.popen、os.system)
- css修改图片形状,用css绘制各种形状