Spring security Spring MongoDB映射OAuth2Authentication
我正在使用MongoDB编写自己的TokenStore实现(org.springframework.security.oauth2.provider.token.TokenStore)。将数据库中的对象转换/映射回Java对象似乎存在一些问题 有人知道我怎么解决这个问题吗Spring security Spring MongoDB映射OAuth2Authentication,spring-security,spring-security-oauth2,spring-mongo,spring-mongodb,Spring Security,Spring Security Oauth2,Spring Mongo,Spring Mongodb,我正在使用MongoDB编写自己的TokenStore实现(org.springframework.security.oauth2.provider.token.TokenStore)。将数据库中的对象转换/映射回Java对象似乎存在一些问题 有人知道我怎么解决这个问题吗 org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.s
org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.security.authentication.UsernamePasswordAuthenticationToken using constructor NO_CONSTRUCTOR with arguments
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:64) ~[spring-data-commons-1.11.0.RELEASE.jar:na]
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83) ~[spring-data-commons-1.11.0.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251) ~[spring-data-mongodb-1.8.0.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231) ~[spring-data-mongodb-1.8.0.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1185) ~[spring-data-mongodb-1.8.0.RELEASE.jar:na]
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$200(MappingMongoConverter.java:78) ~[spring-data-mongodb-1.8.0.RELEASE.jar:na]
您需要创建一个转换器并注册它,因为Spring Mongo不会为您这样做 创建转换器
import com.erranda.abraham.entity.Person;
import com.mongodb.DBObject;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import java.util.*;
/**
* @version 1.0
* @author: Iain Porter
* @since 23/05/2013
*/
//Hackery to deserialize back into an OAuth2Authentication Object made necessary because Spring Mongo can't map clientAuthentication to authorizationRequest
@ReadingConverter
@SuppressWarnings("rawtypes")
public class OAuth2AuthenticationReadConverter implements Converter<DBObject, OAuth2Authentication> {
@Override
@SuppressWarnings("unchecked")
public OAuth2Authentication convert(DBObject source) {
System.out.println(source);
DBObject storedRequest = (DBObject)source.get("storedRequest");
OAuth2Request oAuth2Request = new OAuth2Request((Map<String, String>)storedRequest.get("requestParameters"),
(String)storedRequest.get("clientId"), null, true, new HashSet((List)storedRequest.get("scope")),
null, null, null, null);
DBObject userAuthorization = (DBObject)source.get("userAuthentication");
Object principal = getPrincipalObject(userAuthorization.get("principal"));
Authentication userAuthentication = new UsernamePasswordAuthenticationToken(principal,
(String)userAuthorization.get("credentials"), getAuthorities((List) userAuthorization.get("authorities")));
OAuth2Authentication authentication = new OAuth2Authentication(oAuth2Request,
userAuthentication );
return authentication;
}
private Object getPrincipalObject(Object principal) {
if(principal instanceof DBObject) {
DBObject principalDBObject = (DBObject)principal;
Person user = new Person (principalDBObject);
return user;
} else {
return principal;
}
}
private Collection<GrantedAuthority> getAuthorities(List<Map<String, String>> authorities) {
Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>(authorities.size());
for(Map<String, String> authority : authorities) {
grantedAuthorities.add(new SimpleGrantedAuthority(authority.get("role")));
}
return grantedAuthorities;
}
}
import com.errada.abraham.entity.Person;
导入com.mongodb.DBObject;
导入org.springframework.core.convert.converter.converter;
导入org.springframework.data.convert.ReadingConverter;
导入org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
导入org.springframework.security.core.Authentication;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.SimpleGrantedAuthority;
导入org.springframework.security.oauth2.provider.OAuth2Authentication;
导入org.springframework.security.oauth2.provider.OAuth2Request;
导入java.util.*;
/**
*@version 1.0
*@作者:伊恩·波特
*@自2013年5月23日起
*/
//由于Spring Mongo无法将clientAuthentication映射到authorizationRequest,因此有必要将反序列化回OAuth2Authentication对象
@读取转换器
@抑制警告(“原始类型”)
公共类OAuth2AuthenticationReadConverter实现转换器{
@凌驾
@抑制警告(“未选中”)
公共OAuth2Authentication转换(DBObject源){
系统输出打印项次(来源);
DBObject storedRequest=(DBObject)source.get(“storedRequest”);
OAuth2Request OAuth2Request=新的OAuth2Request((Map)storedRequest.get(“requestParameters”),
(String)storedRequest.get(“clientId”),null,true,新哈希集((List)storedRequest.get(“scope”),
空,空,空,空);
DBObject userAuthorization=(DBObject)source.get(“userAuthorization”);
对象主体=getPrincipalObject(userAuthorization.get(“主体”);
Authentication userAuthentication=新用户名PasswordAuthenticationToken(主体,
(字符串)userAuthorization.get(“凭证”)、getauthorization((列表)userAuthorization.get(“权限”);
OAuth2Authentication authentication=新的OAuth2Authentication(oAuth2Request,
用户身份验证);
返回认证;
}
私有对象getPrincipalObject(对象主体){
if(DBObject的主体实例){
DBObject principalDBObject=(DBObject)principal;
人员用户=新人员(主要对象);
返回用户;
}否则{
返还本金;
}
}
私人收集权限(列表权限){
Set grantedAuthories=newhashset(authorities.size());
对于(地图权限:权限){
grantedAuthories.add(新的SimpleGrantedAuthority(authority.get(“角色”)));
}
返回授权机构;
}
}
然后您需要在mongodb配置旁边注册转换器
import com.erranda.abraham.api.security.OAuth2AuthenticationReadConverter;
import com.mongodb.Mongo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class MongoDbConfiguration extends AbstractMongoConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(MongoDbConfiguration.class);
private static final String MONGO_DB_SERVER = "mongo.db.server";
private static final String MONGO_DB_PORT = "mongo.db.port";
private static final String MONGO_DB_NAME = "mongo.db.name";
private static final String MONGO_DB_LOGON = "mongo.db.logon";
private static final String MONGO_DB_PASSWORD = "mongo.db.password";
private static final String SPRING_PROFILES_ACTIVE = "spring.profiles.active";
@Autowired
private ApplicationContext applicationContext;
@Value("${" + MONGO_DB_SERVER + "}")
private String mongoServer;
@Value("${" + MONGO_DB_PORT + "}")
private int mongoPort;
@Value("${" + MONGO_DB_NAME + "}")
private String mongoDBName;
@Value("${" + MONGO_DB_LOGON + "}")
private String mongoDbLogin;
@Value("${" + MONGO_DB_PASSWORD + "}")
private String mongoDbPassword;
@Override
protected String getDatabaseName() {
return mongoDBName;
}
@Override
@Bean
public Mongo mongo() throws Exception {
return new Mongo(mongoServer, mongoPort);
}
@Override
@Bean
public MongoTemplate mongoTemplate() throws Exception {
if (!StringUtils.isEmpty(mongoDbLogin)) {
LOG.info("Configuring mongoTemplate with credentials.");
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo(), mongoDBName, new UserCredentials(mongoDbLogin, mongoDbPassword));
return new MongoTemplate(mongoDbFactory, mappingMongoConverter());
} else {
LOG.info("Configuring mongoTemplate without credentials.");
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo(), mongoDBName);
return new MongoTemplate(mongoDbFactory, mappingMongoConverter());
}
}
@Override
@Bean
public CustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
OAuth2AuthenticationReadConverter converter = new OAuth2AuthenticationReadConverter();
converterList.add(converter);
return new CustomConversions(converterList);
}
private String getContextProperty(final String propertyKey) {
return applicationContext.getEnvironment().getProperty(propertyKey);
}
}
import com.errada.abraham.api.security.OAuth2AuthenticationReadConverter;
导入com.mongodb.Mongo;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.annotation.Value;
导入org.springframework.context.ApplicationContext;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.core.convert.converter.converter;
导入org.springframework.data.authentication.UserCredentials;
导入org.springframework.data.mongodb.MongoDbFactory;
导入org.springframework.data.mongodb.config.AbstractMongoConfiguration;
导入org.springframework.data.mongodb.core.MongoTemplate;
导入org.springframework.data.mongodb.core.SimpleMongoDbFactory;
导入org.springframework.data.mongodb.core.convert.CustomConversions;
导入org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
导入org.springframework.util.StringUtils;
导入java.util.ArrayList;
导入java.util.List;
@配置
公共类MongoDbConfiguration扩展了AbstractMongoConfiguration{
私有静态最终记录器LOG=LoggerFactory.getLogger(MongoDbConfiguration.class);
私有静态最终字符串MONGO\u DB\u SERVER=“MONGO.DB.SERVER”;
私有静态最终字符串MONGO\u DB\u PORT=“MONGO.DB.PORT”;
私有静态最终字符串MONGO\u DB\u NAME=“MONGO.DB.NAME”;
私有静态最终字符串MONGO\u DB\u LOGON=“MONGO.DB.LOGON”;
私有静态最终字符串MONGO\u DB\u PASSWORD=“MONGO.DB.PASSWORD”;
私有静态最终字符串SPRING\u PROFILES\u ACTIVE=“SPRING.PROFILES.ACTIVE”;
@自动连线
私有应用程序上下文应用程序上下文;
@值(“${”+MONGO_DB_SERVER+“}”)
私有字符串mongoServer;
@值(“${”+MONGO_DB_PORT+“}”)
蒙哥波特私人酒店;
@值(“${”+MONGO_DB_NAME+“}”)
私有字符串mongoDBName;
@值(“${”+MONGO\u DB\u LOGON+“}”)
私有字符串mongoDbLogin;
@值(“${”+MONGO\u DB\u PASSWORD+“}”)
私有字符串mongoDbPassword;
@凌驾
受保护的字符串getDatabaseName(){
返回mongoDBName;
}
@凌驾
@豆子
public Mongo Mongo()引发异常{
返回新的Mongo(mongoServer、mongoPort);
}
@凌驾
@豆子
公共MongoTemplate MongoTemplate()引发异常{
如果(!StringUtils.isEmpty(mongoDbLogin)){
LOG.info(“使用凭据配置mongoTemplate”);
MongoDbFactory MongoDbFactory=newsimplemongodbfactory(mongo(),mongoDBName,newusercredentials(mongoDbLogin,mongoDbPassword));
返回新的MongoTemplate(mongoDbFactory,mappingMongoConverter());
}否则{
LOG.info(“配置mong