1, the use of technology and version number JDK8.0 Spring 5.0 oauth2.0 redis2.0
2, the project uses MAVEN management. Pom File Add: <
Dependency> <
groupId> Org.springframework.cloud </
groupId> <
Artifactid> Spring-cloud-starter-security </
Artifactid> </
Dependency>
<
Dependency> <
groupId> Org.springframework.cloud </
groupId> <
Artifactid> Spring-cloud-starter-oauth2 </
Artifactid> </
Dependency>
<
Dependency> <
groupId> Org.springframework.boot </
groupId> <
Artifactid> Spring-boot-starter-data-redis </
Artifactid> </
Dependency>
<
Dependency> <
groupId> Org.springframework.boot </
groupId> <
Artifactid> SPRING-BOOT-STARTER-DATA-JPA </
Artifactid> </
Dependency>
<
Dependency> <
groupId> Org.thymeleaf </
groupId> <
Artifactid> Thymeleaf-spring5 </
Artifactid> </
Dependency>
3, the data storage is using Redis to store. So the decision token stored in the Redis, the client information and the code information are saved in the database table. OAUTH2.0 related to the database table has detailed description: http://andaily.com/spring-oauth-server/db_table_description.html
4, Spring5.0 new version, there are many methods and classes have changed, resulting in most of the online authentication code can not be used, run an error. After inquiry and research. It's finally running. Note: redisconnectionfactory Save token error, this time need to customize the Myredistokenstore class, to achieve tokenstore. Myredistokenstore and Redistokenstore code almost the same, just put all conn.set (...) All changed to Conn. Stringcommands (). Set (...), passwordencoder password verification ClientID will error, because 5.0 new features need to be in front of the password need to add {Xxx} to distinguish. So you need to customize a class to Bcryptpasswordencoder the match method.
In short, there are a lot of holes, we have only one step a hole slowly forward to landfills.
5,
Related learning materials oauth2.0+security Related materials: https://www.cnblogs.com/sheng-jie/p/6564520.html Https://developers.douban.com/wiki /?title=oauth2 http://andaily.com/spring-oauth-server/db_table_description.html http://blog.csdn.net/greatneyo/ article/details/77979848 http://www.tianshouzhi.com/api/tutorials/spring_security_4/264 https://www.cnblogs.com/ Xingxueliao/p/5911292.html https://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/ Springframework/security/config/annotation/web/builders/httpsecurity.html
There are bugs, need to find solutions, if the Baidu inside did not find the relevant information, you can find in the https://stackoverflow.com/.
reids2.0 Related information: https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#new-in-2.0.0.
6, the core code:
Package com.hbasesoft.vcc.sgp.ability.oauth.server.config;
Import Com.hbasesoft.framework.db.core.config.DbParam;
Import Com.hbasesoft.framework.db.core.utils.DataSourceUtil;
Import Com.hbasesoft.vcc.sgp.ability.oauth.server.security.MyBCryptPasswordEncoder;
Import Com.hbasesoft.vcc.sgp.ability.oauth.server.security.MyRedisTokenStore;
Import org.springframework.beans.factory.annotation.Autowired;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;
Import Org.springframework.data.redis.connection.RedisConnectionFactory;
Import Org.springframework.security.authentication.AuthenticationManager;
Import Org.springframework.security.crypto.password.PasswordEncoder;
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.ClientDetailsService;
Import Org.springframework.security.oauth2.provider.approval.ApprovalStore;
Import Org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
Import Org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
Import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
Import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
Import Org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
Import Javax.sql.DataSource; /** * @Author: FB * @Description client information to query database validation through JDBC (annotation part is validated by Redis method) * @Date: Create in 14:54 2018/2/1 * @Modified by */@Configuration @EnableAuthorizationServer public class Oauthserverconfig extends Authorizat
Ionserverconfigureradapter {@Autowired private authenticationmanager AuthenticationManager; This system obtains DataSource way private DataSource DataSource = Datasourceutil.registdatasource ("Master", New Dbparam ("Master")
;
@Autowired private Redisconnectionfactory ConnectionFactory;
@Bean public Passwordencoder Passwordencoder () {return new Mybcryptpasswordencoder ();
}/* @Autowired private clientdetailsservice clientdetailsservice;
* * @Bean public Myredistokenstore Tokenstore () {return new Myredistokenstore (connectionfactory); @Bean public authorizationcodeservices authorizationcodeservices () {return new Jdbcauthorizationcodese
Rvices (DataSource); @Bean public Clientdetailsservice Clientdetailsservice () {return new Jdbcclientdetailsservice (DatasouRCE);
@Bean public Approvalstore Approvalstore () {Tokenapprovalstore store = new Tokenapprovalstore ();
Store.settokenstore (Tokenstore ());
return store; }/* @Bean public Userapprovalhandler Userapprovalhandler () throws Exception {Myuserapprovalhandler
Handler = new Myuserapprovalhandler ();
Handler.setapprovalstore (Approvalstore ());
Handler.setclientdetailsservice (Clientdetailsservice);
Handler.setrequestfactory (New Defaultoauth2requestfactory (Clientdetailsservice));
Handler.setuseapprovalstore (TRUE);
return handler; } */@Override public void Configure (Clientdetailsserviceconfigurer clients) throws Exception {///
Client information through Redis to obtain validation//FINAL Redisclientdetailsservicebuilder builder = new Redisclientdetailsservicebuilder ();
Clients.setbuilder (builder); Through JDBC to query the database oauth_client_details table verify ClientID information CLIENTS.JDBC (This.datasource). Clients (This.clientdetailsservice ()); @Override public void Configure (Authorizationserverendpointsconfigurer endpoints) throws Exception {en Dpoints.authenticationmanager (AuthenticationManager). Tokenstore (This.tokenstore ())//. US Erdetailsservice (Userdetailsservice)//. Userapprovalhandler (Userapprovalhandler ()). Autho
Rizationcodeservices (This.authorizationcodeservices ()); @Override public void Configure (Authorizationserversecurityconfigurer oauthserver) throws Exception {O
Authserver.tokenkeyaccess ("Permitall ()"). Checktokenaccess ("isauthenticated ()"); }
}
The above code datasource is our frame system encapsulation good, if you datasource not the encapsulation is good, then directly uses
@Autowired
private DataSource DataSource;
The Mybcryptpasswordencoder class is a custom class that I use to recreate the match method.
package com.hbasesoft.vcc.sgp.ability.oauth.server.security;
Import Org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
Import org.springframework.security.crypto.factory.PasswordEncoderFactories;
Import Org.springframework.security.crypto.password.PasswordEncoder; /** * <Description> <br> * * @author fb<br> * @version 1.0<br> * @taskId <br> * @Creat EDate Create in 13:50 2018/2/12 * @see com.hbasesoft.vcc.sgp.ability.oauth.server.security <br> * @since v1.0<b r> */public class Mybcryptpasswordencoder extends Bcryptpasswordencoder {@Override public boolean matches (Ch Arsequence Rawpassword, String encodedpassword) {Passwordencoder Passwordencoder = passwordencoderfactories.creat
Edelegatingpasswordencoder ();
String Presentedpassword =passwordencoder.encode (Encodedpassword);
Return Passwordencoder.matches (Rawpassword, Presentedpassword); }
}
In the above class, the client information is stored in the database, and the token information is stored in the Redis, Redis is implemented with Redistokenstore, but the following error occurs in Spring 5.0:
I upgraded my spring boot project version to 2.0.0.M7, integrated the spring security Oauth2 (the default version), Redis (the default version), and used Redis to store token. After the project starts normally, request token times to be wrong
Nested exception is Java.lang.NoSuchMethodError:org.springframework.data.redis.connection.RedisConnection.set ([b[ B) V
When I saw the error message, my first reaction was version conflict, but I relied on the default version in Spring-boot-starter-parent. Set (string,string) is deprecated in the Pring-data-redis 2.0 version. Then I follow the Web page of the solution "Spring-date-redis" to 2.0.1.RELEASE and "Jedis" as 2.9.0 (explicit declaration), the result is the same error. Solved in an extreme way. Set (string,string) is deprecated in the Spring-data-redis version 2.0, to use Redisconnection.stringcommands (). Set (...), All I have to customize a Redistokenstore, code and Redistokenstore, just put all conn.set (...) All changed to Conn. Stringcommands (). Set (...), the test method is feasible.
The Myredistokenstore.java class code is as follows:
Package com.hbasesoft.vcc.sgp.ability.oauth.server.security;
Import java.util.ArrayList;
Import java.util.Collection;
Import java.util.Collections;
Import Java.util.Date;
Import Java.util.Iterator;
Import java.util.List;
Import org.springframework.data.redis.connection.RedisConnection;
Import Org.springframework.data.redis.connection.RedisConnectionFactory;
Import Org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
Import Org.springframework.security.oauth2.common.OAuth2AccessToken;
Import Org.springframework.security.oauth2.common.OAuth2RefreshToken;
Import org.springframework.security.oauth2.provider.OAuth2Authentication;
Import Org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
Import Org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
Import Org.springframework.security.oauth2.provider.token.TokenStore;
Import Org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy; ImpORT org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;
Import org.springframework.stereotype.Component;
Import java.util.*; /** * <Description> rewrite Tokenstore. Because the latest version of Redistokenstore set has been deprecated, * so I can only customize one, code and Redistokenstore, * just put all the CO Nn.set (...) All changed to Conn. Stringcommands (). Set (...), * <br> * * @author fb<br> * @version 1.0<br> * @taskId <br> * @Crea Tedate Create in 10:59 2018/2/13 * @see com.hbasesoft.vcc.sgp.ability.oauth.server.security <br> * @since v1.0< Br>/@Component public class Myredistokenstore implements Tokenstore {private static final String ACCESS = "acc
ESS: ";
private static final String auth_to_access = "auth_to_access:";
private static final String AUTH = "AUTH:";
private static final String Refresh_auth = "Refresh_auth:";
private static final String Access_to_refresh = "Access_to_refresh:";
Private static final String refresh = "Refresh:";private static final String refresh_to_access = "refresh_to_access:";
private static final String client_id_to_access = "client_id_to_access:";
private static final String uname_to_access = "uname_to_access:";
Private final redisconnectionfactory ConnectionFactory;
Private Authenticationkeygenerator Authenticationkeygenerator = new Defaultauthenticationkeygenerator ();
Private Redistokenstoreserializationstrategy serializationstrategy = new Jdkserializationstrategy ();
Private String prefix = "";
Public Myredistokenstore (Redisconnectionfactory connectionfactory) {this.connectionfactory = connectionFactory; } public void Setauthenticationkeygenerator (Authenticationkeygenerator authenticationkeygenerator) {this.
Authenticationkeygenerator = Authenticationkeygenerator; } public void Setserializationstrategy (Redistokenstoreserializationstrategy serializationstrategy) {This.ser
Ializationstrategy = Serializationstrategy; } public void Setprefix (String prefix) {this.prefix = prefix;
Private Redisconnection getconnection () {return this.connectionFactory.getConnection ();
Private byte[] Serialize (object) {return This.serializationStrategy.serialize (object);
Private byte[] Serializekey (String object) {return this.serialize (This.prefix + object); Private Oauth2accesstoken deserializeaccesstoken (byte[] bytes) {return (Oauth2accesstoken) This.serializati
Onstrategy.deserialize (bytes, oauth2accesstoken.class); Private Oauth2authentication deserializeauthentication (byte[] bytes) {return (oauth2authentication) this.se
Rializationstrategy.deserialize (bytes, oauth2authentication.class); Private Oauth2refreshtoken deserializerefreshtoken (byte[] bytes) {return (Oauth2refreshtoken) This.serializ
Ationstrategy.deserialize (bytes, oauth2refreshtoken.class); } private byte[] sErialize (String string) {return this.serializationStrategy.serialize (string); Private String deserializestring (byte[] bytes) {return This.serializationStrategy.deseri