Import Mongodb branch codes

mongodb
Li Shengzhao 2016-04-14 23:45:28 +08:00
parent d037885a36
commit 8642601e71
45 changed files with 1909 additions and 909 deletions

126
pom.xml
View File

@ -4,12 +4,12 @@
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>monkeyk.com</groupId>
<groupId>com.monkeyk</groupId>
<artifactId>spring-oauth-server</artifactId>
<version>0.5-beta</version>
<name>spring-oauth-server</name>
<packaging>war</packaging>
<description>Spring Oauth Server</description>
<description>Spring Oauth Server[MongoDB]</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -18,16 +18,8 @@
<spring.security.version>4.0.1.RELEASE</spring.security.version>
<spring.security.oauth.version>2.0.7.RELEASE</spring.security.oauth.version>
<fasterxml.jackson.version>2.5.4</fasterxml.jackson.version>
<aspectj.version>1.8.6</aspectj.version>
<!--jdbc execute sql config-->
<jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
<jdbc.url>jdbc:mysql://localhost:3306/oauth2_test?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8</jdbc.url>
<jdbc.user>andaily</jdbc.user>
<jdbc.pass>andaily</jdbc.pass>
<!--if do not use execute sql, change the value to true-->
<jdbc.execute.skip>false</jdbc.execute.skip>
<test.skip>false</test.skip>
</properties>
@ -77,45 +69,6 @@
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.4</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driver}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.user}</username>
<password>${jdbc.pass}</password>
<skip>${jdbc.execute.skip}</skip>
</configuration>
<executions>
<execution>
<id>init db</id>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>${jdbc.url}</url>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>others/database/initial_db.ddl</srcFile>
<srcFile>others/database/oauth.ddl</srcFile>
</srcFiles>
<onError>continue</onError>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4</version>
@ -125,20 +78,6 @@
<includes>
<include>**/*Test.java</include>
</includes>
<systemProperties>
<property>
<name>jdbc.url</name>
<value>${jdbc.url}</value>
</property>
<property>
<name>jdbc.username</name>
<value>${jdbc.user}</value>
</property>
<property>
<name>jdbc.password</name>
<value>${jdbc.pass}</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
@ -200,9 +139,9 @@
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
@ -210,11 +149,6 @@
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
@ -246,6 +180,7 @@
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
@ -271,11 +206,23 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.security</groupId>-->
@ -299,21 +246,20 @@
<version>${spring.security.oauth.version}</version>
</dependency>
<!--json-->
<!--MongoDB-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.jackson.version}</version>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>compile</scope>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.13.3</version>
</dependency>
<!--log-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
@ -327,6 +273,26 @@
<scope>compile</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>net.sf.json-lib</groupId>-->
<!--<artifactId>json-lib</artifactId>-->
<!--<version>2.4</version>-->
<!--<classifier>jdk15</classifier>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>commons-logging</groupId>-->
<!--<artifactId>commons-logging</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<!--json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>

View File

@ -1,95 +0,0 @@
package com.monkeyk.sos.domain;
import com.monkeyk.sos.domain.shared.GuidGenerator;
import com.monkeyk.sos.infrastructure.DateUtils;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author Shengzhao Li
*/
public abstract class AbstractDomain implements Serializable {
private static final long serialVersionUID = 6569365774429340632L;
/**
* Database id
*/
protected int id;
protected boolean archived;
/**
* Domain business guid.
*/
protected String guid = GuidGenerator.generate();
/**
* The domain create time.
*/
protected LocalDateTime createTime = DateUtils.now();
public AbstractDomain() {
}
public int id() {
return id;
}
public void id(int id) {
this.id = id;
}
public boolean archived() {
return archived;
}
public AbstractDomain archived(boolean archived) {
this.archived = archived;
return this;
}
public String guid() {
return guid;
}
public void guid(String guid) {
this.guid = guid;
}
public LocalDateTime createTime() {
return createTime;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof AbstractDomain)) {
return false;
}
AbstractDomain that = (AbstractDomain) o;
return guid.equals(that.guid);
}
@Override
public int hashCode() {
return guid.hashCode();
}
//For subclass override it
public void saveOrUpdate() {
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("{id=").append(id);
sb.append(", archived=").append(archived);
sb.append(", guid='").append(guid).append('\'');
sb.append(", createTime=").append(createTime);
sb.append('}');
return sb.toString();
}
}

View File

@ -13,11 +13,14 @@ package com.monkeyk.sos.domain.dto;
import com.monkeyk.sos.domain.user.Privilege;
import com.monkeyk.sos.domain.user.User;
import com.monkeyk.sos.infrastructure.DateUtils;
import java.io.Serializable;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 2016/3/12
@ -37,7 +40,7 @@ public class UserDto implements Serializable {
private String createTime;
private List<Privilege> privileges = new ArrayList<>();
private Set<Privilege> privileges = new HashSet<>();
public UserDto() {
@ -51,7 +54,7 @@ public class UserDto implements Serializable {
this.email = user.email();
this.privileges = user.privileges();
this.createTime = user.createTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
this.createTime = DateUtils.toDateTime(user.createTime());
}
public String getCreateTime() {
@ -94,19 +97,17 @@ public class UserDto implements Serializable {
this.email = email;
}
public List<Privilege> getPrivileges() {
public Set<Privilege> getPrivileges() {
return privileges;
}
public void setPrivileges(List<Privilege> privileges) {
public void setPrivileges(Set<Privilege> privileges) {
this.privileges = privileges;
}
public static List<UserDto> toDtos(List<User> users) {
List<UserDto> dtos = new ArrayList<>(users.size());
for (User user : users) {
dtos.add(new UserDto(user));
}
dtos.addAll(users.stream().map(UserDto::new).collect(Collectors.toList()));
return dtos;
}
}

View File

@ -6,6 +6,8 @@ import com.monkeyk.sos.domain.user.User;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author Shengzhao Li
@ -13,6 +15,7 @@ import java.util.List;
public class UserJsonDto implements Serializable {
private static final long serialVersionUID = 3323307820018705154L;
private String guid;
private boolean archived;
@ -33,10 +36,8 @@ public class UserJsonDto implements Serializable {
this.phone = user.phone();
this.email = user.email();
final List<Privilege> privilegeList = user.privileges();
for (Privilege privilege : privilegeList) {
this.privileges.add(privilege.name());
}
final Set<Privilege> privilegeList = user.privileges();
this.privileges.addAll(privilegeList.stream().map(Privilege::name).collect(Collectors.toList()));
}
public boolean isArchived() {

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.SerializationUtils;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import java.io.Serializable;
import java.util.Date;
/**
* 2015/10/29
*
* @author Shengzhao Li
*/
@Document(collection = "AccessToken")
public class AccessToken implements Serializable {
private static final long serialVersionUID = 7588602587200382326L;
@Id
private String tokenId;
@CreatedDate
private Date createTime = DateUtils.now();
@Version
private Long version;
private byte[] token;
private String authenticationId;
private byte[] authentication;
private String username;
private String clientId;
private String refreshToken;
public AccessToken() {
}
public String tokenId() {
return tokenId;
}
public AccessToken tokenId(String tokenId) {
this.tokenId = tokenId;
return this;
}
public Date createTime() {
return createTime;
}
public Long version() {
return version;
}
public OAuth2AccessToken token() {
return SerializationUtils.deserialize(token);
}
public AccessToken token(OAuth2AccessToken token) {
this.token = SerializationUtils.serialize(token);
return this;
}
public String authenticationId() {
return authenticationId;
}
public AccessToken authenticationId(String authenticationId) {
this.authenticationId = authenticationId;
return this;
}
public OAuth2Authentication authentication() {
return SerializationUtils.deserialize(authentication);
}
public AccessToken authentication(OAuth2Authentication authentication) {
this.authentication = SerializationUtils.serialize(authentication);
return this;
}
public String username() {
return username;
}
public AccessToken username(String username) {
this.username = username;
return this;
}
public String clientId() {
return clientId;
}
public AccessToken clientId(String clientId) {
this.clientId = clientId;
return this;
}
public String refreshToken() {
return refreshToken;
}
public AccessToken refreshToken(String refreshToken) {
this.refreshToken = refreshToken;
return this;
}
@Override
public String toString() {
return "{" +
"tokenId='" + tokenId + '\'' +
", createTime=" + createTime +
", version=" + version +
", authenticationId='" + authenticationId + '\'' +
", username='" + username + '\'' +
", clientId='" + clientId + '\'' +
", refreshToken='" + refreshToken + '\'' +
'}';
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.domain.shared.Repository;
import java.util.List;
/**
* 2015/10/29
*
* @author Shengzhao Li
*/
public interface AccessTokenRepository extends Repository {
void saveAccessToken(AccessToken accessToken);
AccessToken findAccessToken(String tokenId);
void removeAccessToken(String tokenId);
void saveRefreshToken(RefreshToken refreshToken);
RefreshToken findRefreshToken(String tokenId);
void removeRefreshToken(String tokenId);
void removeAccessTokenByRefreshToken(String refreshToken);
AccessToken findAccessTokenByRefreshToken(String refreshToken);
AccessToken findAccessTokenByAuthenticationId(String authenticationId);
List<AccessToken> findAccessTokensByUsername(String userName);
List<AccessToken> findAccessTokensByClientId(String clientId);
List<AccessToken> findAccessTokensByClientIdAndUsername(String clientId, String userName);
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.oauth2.common.util.SerializationUtils;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import java.io.Serializable;
import java.util.Date;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
@Document(collection = "AuthorizationCode")
public class AuthorizationCode implements Serializable {
private static final long serialVersionUID = 2775272095671208572L;
@Id
private String code;
@CreatedDate
private Date createTime = DateUtils.now();
@Version
private Long version;
private byte[] authenticationBytes;
public AuthorizationCode() {
}
public String code() {
return code;
}
public AuthorizationCode code(String code) {
this.code = code;
return this;
}
public Date createTime() {
return createTime;
}
public Long version() {
return version;
}
public OAuth2Authentication authentication() {
return SerializationUtils.deserialize(authenticationBytes);
}
public AuthorizationCode authentication(OAuth2Authentication authentication) {
this.authenticationBytes = SerializationUtils.serialize(authentication);
return this;
}
@Override
public String toString() {
return "{" +
"code='" + code + '\'' +
", createTime=" + createTime +
", version=" + version +
", authenticationBytes=" + authenticationBytes +
'}';
}
}

View File

@ -1,25 +0,0 @@
package com.monkeyk.sos.domain.oauth;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import javax.sql.DataSource;
/**
* Add <i>archived = 0</i> condition
*
* @author Shengzhao Li
*/
public class CustomJdbcClientDetailsService extends JdbcClientDetailsService {
private static final String SELECT_CLIENT_DETAILS_SQL = "select client_id, client_secret, resource_ids, scope, authorized_grant_types, " +
"web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove " +
"from oauth_client_details where client_id = ? and archived = 0 ";
public CustomJdbcClientDetailsService(DataSource dataSource) {
super(dataSource);
setSelectClientDetailsSql(SELECT_CLIENT_DETAILS_SQL);
}
}

View File

@ -1,22 +1,38 @@
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @author Shengzhao Li
*/
@Document(collection = "OauthClientDetails")
public class OauthClientDetails implements Serializable {
private static final long serialVersionUID = 3186665658971862447L;
private static final long serialVersionUID = -6947822646185526939L;
private LocalDateTime createTime = DateUtils.now();
@Id
private String clientId;
@CreatedDate
private Date createTime = DateUtils.now();
@Version
private Long version;
private boolean archived = false;
private String clientId;
private String resourceIds;
private String clientSecret;
@ -48,12 +64,14 @@ public class OauthClientDetails implements Serializable {
/**
* The access token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
* Unit: second
*/
private Integer accessTokenValidity;
/**
* The refresh token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
* Unit: second
*/
private Integer refreshTokenValidity;
@ -66,40 +84,44 @@ public class OauthClientDetails implements Serializable {
*/
private boolean trusted = false;
/**
* Value is 'true' or 'false', default 'false'
*/
private String autoApprove;
public OauthClientDetails() {
}
public String autoApprove() {
return autoApprove;
public ClientDetails toClientDetails() {
BaseClientDetails clientDetails = new BaseClientDetails(clientId, resourceIds, scope, authorizedGrantTypes, authorities, webServerRedirectUri);
clientDetails.setClientSecret(clientSecret);
if (StringUtils.isNotEmpty(additionalInformation)) {
clientDetails.addAdditionalInformation("information", additionalInformation);
}
clientDetails.setAccessTokenValiditySeconds(accessTokenValidity);
clientDetails.setRefreshTokenValiditySeconds(refreshTokenValidity);
return clientDetails;
}
public OauthClientDetails autoApprove(String autoApprove) {
this.autoApprove = autoApprove;
return this;
public Long version() {
return version;
}
public boolean trusted() {
return trusted;
}
public LocalDateTime createTime() {
public Date createTime() {
return createTime;
}
public OauthClientDetails createTime(LocalDateTime createTime) {
this.createTime = createTime;
return this;
}
public boolean archived() {
return archived;
}
public OauthClientDetails archived(boolean archived) {
this.archived = archived;
return this;
}
public String clientId() {
return clientId;
}
@ -157,6 +179,7 @@ public class OauthClientDetails implements Serializable {
sb.append(", accessTokenValidity=").append(accessTokenValidity);
sb.append(", refreshTokenValidity=").append(refreshTokenValidity);
sb.append(", additionalInformation='").append(additionalInformation).append('\'');
sb.append(", version='").append(version).append('\'');
sb.append(", trusted=").append(trusted);
sb.append('}');
return sb.toString();
@ -216,9 +239,4 @@ public class OauthClientDetails implements Serializable {
this.additionalInformation = additionalInformation;
return this;
}
public OauthClientDetails archived(boolean archived) {
this.archived = archived;
return this;
}
}

View File

@ -13,7 +13,13 @@ public interface OauthRepository extends Repository {
List<OauthClientDetails> findAllOauthClientDetails();
void updateOauthClientDetailsArchive(String clientId, boolean archive);
boolean updateOauthClientDetailsArchive(String clientId, boolean archive);
void saveOauthClientDetails(OauthClientDetails clientDetails);
boolean removeOauthClientDetails(OauthClientDetails clientDetails);
void saveAuthorizationCode(AuthorizationCode authorizationCode);
AuthorizationCode removeAuthorizationCode(String code);
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.common.util.SerializationUtils;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import java.io.Serializable;
import java.util.Date;
/**
* 2015/10/29
*
* @author Shengzhao Li
*/
@Document(collection = "RefreshToken")
public class RefreshToken implements Serializable {
private static final long serialVersionUID = 5529390717010301531L;
@Id
private String tokenId;
@CreatedDate
private Date createTime = DateUtils.now();
@Version
private Long version;
private byte[] token;
private byte[] authentication;
public RefreshToken() {
}
public String tokenId() {
return tokenId;
}
public RefreshToken tokenId(String tokenId) {
this.tokenId = tokenId;
return this;
}
public Date createTime() {
return createTime;
}
public Long version() {
return version;
}
public OAuth2RefreshToken token() {
return SerializationUtils.deserialize(token);
}
public RefreshToken token(OAuth2RefreshToken token) {
this.token = SerializationUtils.serialize(token);
return this;
}
public OAuth2Authentication authentication() {
return SerializationUtils.deserialize(authentication);
}
public RefreshToken authentication(OAuth2Authentication authentication) {
this.authentication = SerializationUtils.serialize(authentication);
return this;
}
@Override
public String toString() {
return "{" +
"tokenId='" + tokenId + '\'' +
", createTime=" + createTime +
", version=" + version +
'}';
}
}

View File

@ -0,0 +1,41 @@
package com.monkeyk.sos.domain.shared;
import org.springframework.context.ApplicationContext;
/**
* @author Shengzhao Li
*/
public abstract class BeanProvider {
private static ApplicationContext applicationContext;
private BeanProvider() {
}
public static void initialize(ApplicationContext applicationContext) {
BeanProvider.applicationContext = applicationContext;
}
/**
* Get Bean by clazz.
*
* @param clazz Class
* @param <T> class type
* @return Bean instance
*/
public static <T> T getBean(Class<T> clazz) {
if (applicationContext == null) {
return null;
}
return applicationContext.getBean(clazz);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanId) {
if (applicationContext == null) {
return null;
}
return (T) applicationContext.getBean(beanId);
}
}

View File

@ -9,6 +9,8 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author Shengzhao Li
@ -40,10 +42,8 @@ public class WdcyUserDetails implements UserDetails {
this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + Privilege.UNITY.name()));
this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + Privilege.MOBILE.name()));
} else {
final List<Privilege> privileges = user.privileges();
for (Privilege privilege : privileges) {
this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + privilege.name()));
}
final Set<Privilege> privileges = user.privileges();
this.grantedAuthorities.addAll(privileges.stream().map(privilege -> new SimpleGrantedAuthority(ROLE_PREFIX + privilege.name())).collect(Collectors.toList()));
}
}
@ -94,9 +94,6 @@ public class WdcyUserDetails implements UserDetails {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("{user=").append(user);
sb.append('}');
return sb.toString();
return "{user=" + user + '}';
}
}

View File

@ -1,32 +1,54 @@
package com.monkeyk.sos.domain.user;
import com.monkeyk.sos.domain.AbstractDomain;
import java.time.LocalDateTime;
import java.util.ArrayList;
import com.monkeyk.sos.domain.shared.GuidGenerator;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
/**
* @author Shengzhao Li
*/
public class User extends AbstractDomain {
@Document(collection = "user_")
public class User implements Serializable {
private static final long serialVersionUID = -2921689304753120556L;
private static final long serialVersionUID = -6117108610171201352L;
@Id
private String guid = GuidGenerator.generate();
@CreatedDate
private Date createTime = DateUtils.now();
@Version
private Long version;
//unique
private String username;
private String password;
private String phone;
private String email;
//Default user is initial when create database, do not delete
//Default user is initialed
private boolean defaultUser = false;
private Date lastLoginTime;
private List<Privilege> privileges = new ArrayList<>();
private Set<Privilege> privileges = new HashSet<>();
private boolean archived = false;
public User() {
}
@ -38,6 +60,15 @@ public class User extends AbstractDomain {
this.email = email;
}
public Long version() {
return version;
}
public String guid() {
return guid;
}
public boolean defaultUser() {
return defaultUser;
}
@ -50,6 +81,11 @@ public class User extends AbstractDomain {
return password;
}
public User password(String password) {
this.password = password;
return this;
}
public String phone() {
return phone;
}
@ -58,21 +94,27 @@ public class User extends AbstractDomain {
return email;
}
public List<Privilege> privileges() {
public Set<Privilege> privileges() {
return privileges;
}
public Date createTime() {
return createTime;
}
public boolean archived() {
return archived;
}
public User archived(boolean archived) {
this.archived = archived;
return this;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("{username='").append(username).append('\'');
sb.append(", phone='").append(phone).append('\'');
sb.append(", id='").append(id).append('\'');
sb.append(", guid='").append(guid).append('\'');
sb.append(", defaultUser='").append(defaultUser).append('\'');
sb.append(", email='").append(email).append('\'');
sb.append('}');
return sb.toString();
return "{username='" + username + '\'' + ", phone='" + phone + '\'' + ", version='" + version + '\'' + ", defaultUser='" + defaultUser + '\'' + ", email='" + email + '\'' + '}';
}
public User email(String email) {
@ -96,18 +138,7 @@ public class User extends AbstractDomain {
return lastLoginTime;
}
public User lastLoginTime(Date lastLoginTime) {
public void lastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
return this;
}
public User createTime(LocalDateTime createTime) {
this.createTime = createTime;
return this;
}
public User password(String password) {
this.password = password;
return this;
}
}

View File

@ -14,9 +14,13 @@ public interface UserRepository extends Repository {
void saveUser(User user);
void updateUser(User user);
boolean updateUser(User user);
User findByUsername(String username);
List<User> findAllUsers();
boolean removeUser(User user);
List<User> findUsersByUsername(String username);
}

View File

@ -3,6 +3,7 @@ package com.monkeyk.sos.infrastructure;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
/**
@ -19,8 +20,8 @@ public abstract class DateUtils {
private DateUtils() {
}
public static LocalDateTime now() {
return LocalDateTime.now();
public static Date now() {
return new Date();
}
@ -28,12 +29,15 @@ public abstract class DateUtils {
return toDateTime(date, DEFAULT_DATE_TIME_FORMAT);
}
public static String toDateTime(Date date) {
return toDateTime(LocalDateTime.from(date.toInstant()), DEFAULT_DATE_TIME_FORMAT);
}
public static String toDateTime(LocalDateTime dateTime, String pattern) {
return dateTime.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE));
}
public static String toDateText(LocalDate date, String pattern) {
if (date == null || pattern == null) {
return null;

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.ZoneId;
/**
* 2015/11/16
*
* @author Shengzhao Li
*/
public class OauthClientDetailsRowMapper implements RowMapper<OauthClientDetails> {
public OauthClientDetailsRowMapper() {
}
@Override
public OauthClientDetails mapRow(ResultSet rs, int i) throws SQLException {
OauthClientDetails clientDetails = new OauthClientDetails();
clientDetails.clientId(rs.getString("client_id"));
clientDetails.resourceIds(rs.getString("resource_ids"));
clientDetails.clientSecret(rs.getString("client_secret"));
clientDetails.scope(rs.getString("scope"));
clientDetails.authorizedGrantTypes(rs.getString("authorized_grant_types"));
clientDetails.webServerRedirectUri(rs.getString("web_server_redirect_uri"));
clientDetails.authorities(rs.getString("authorities"));
clientDetails.accessTokenValidity(getInteger(rs, "access_token_validity"));
clientDetails.refreshTokenValidity(getInteger(rs, "refresh_token_validity"));
clientDetails.additionalInformation(rs.getString("additional_information"));
clientDetails.createTime(rs.getTimestamp("create_time").toLocalDateTime());
clientDetails.archived(rs.getBoolean("archived"));
clientDetails.trusted(rs.getBoolean("trusted"));
clientDetails.autoApprove(rs.getString("autoapprove"));
return clientDetails;
}
private Integer getInteger(ResultSet rs, String columnName) throws SQLException {
final Object object = rs.getObject(columnName);
if (object != null) {
return (Integer) object;
}
return null;
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import com.monkeyk.sos.domain.oauth.OauthRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 2015/11/16
*
* @author Shengzhao Li
*/
@Repository("oauthRepositoryJdbc")
public class OauthRepositoryJdbc implements OauthRepository {
private static OauthClientDetailsRowMapper oauthClientDetailsRowMapper = new OauthClientDetailsRowMapper();
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public OauthClientDetails findOauthClientDetails(String clientId) {
final String sql = " select * from oauth_client_details where client_id = ? ";
final List<OauthClientDetails> list = this.jdbcTemplate.query(sql, new Object[]{clientId}, oauthClientDetailsRowMapper);
return list.isEmpty() ? null : list.get(0);
}
@Override
public List<OauthClientDetails> findAllOauthClientDetails() {
final String sql = " select * from oauth_client_details order by create_time desc ";
return this.jdbcTemplate.query(sql, oauthClientDetailsRowMapper);
}
@Override
public void updateOauthClientDetailsArchive(String clientId, boolean archive) {
final String sql = " update oauth_client_details set archived = ? where client_id = ? ";
this.jdbcTemplate.update(sql, archive, clientId);
}
@Override
public void saveOauthClientDetails(final OauthClientDetails clientDetails) {
final String sql = " insert into oauth_client_details(client_id,resource_ids,client_secret,scope,authorized_grant_types,web_server_redirect_uri," +
" authorities,access_token_validity,refresh_token_validity,additional_information,trusted,autoapprove) values (?,?,?,?,?,?,?,?,?,?,?,?)";
this.jdbcTemplate.update(sql, ps -> {
ps.setString(1, clientDetails.clientId());
ps.setString(2, clientDetails.resourceIds());
ps.setString(3, clientDetails.clientSecret());
ps.setString(4, clientDetails.scope());
ps.setString(5, clientDetails.authorizedGrantTypes());
ps.setString(6, clientDetails.webServerRedirectUri());
ps.setString(7, clientDetails.authorities());
ps.setObject(8, clientDetails.accessTokenValidity());
ps.setObject(9, clientDetails.refreshTokenValidity());
ps.setString(10, clientDetails.additionalInformation());
ps.setBoolean(11, clientDetails.trusted());
ps.setString(12, clientDetails.autoApprove());
});
}
}

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.user.Privilege;
import com.monkeyk.sos.domain.user.User;
import com.monkeyk.sos.domain.user.UserRepository;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* 2015/11/16
*
* @author Shengzhao Li
*/
@Repository("userRepositoryJdbc")
public class UserRepositoryJdbc implements UserRepository {
private static UserRowMapper userRowMapper = new UserRowMapper();
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public User findByGuid(String guid) {
final String sql = " select * from user_ where guid = ? ";
final List<User> list = this.jdbcTemplate.query(sql, new Object[]{guid}, userRowMapper);
User user = null;
if (!list.isEmpty()) {
user = list.get(0);
user.privileges().addAll(findPrivileges(user.id()));
}
return user;
}
private Collection<Privilege> findPrivileges(int userId) {
final String sql = " select privilege from user_privilege where user_id = ? ";
final List<String> strings = this.jdbcTemplate.queryForList(sql, new Object[]{userId}, String.class);
List<Privilege> privileges = new ArrayList<>(strings.size());
privileges.addAll(strings.stream().map(Privilege::valueOf).collect(Collectors.toList()));
return privileges;
}
@Override
public void saveUser(final User user) {
final String sql = " insert into user_(guid,archived,create_time,email,password,username,phone) " +
" values (?,?,?,?,?,?,?) ";
this.jdbcTemplate.update(sql, ps -> {
ps.setString(1, user.guid());
ps.setBoolean(2, user.archived());
ps.setTimestamp(3, Timestamp.valueOf(user.createTime()));
ps.setString(4, user.email());
ps.setString(5, user.password());
ps.setString(6, user.username());
ps.setString(7, user.phone());
});
//get user id
final Integer id = this.jdbcTemplate.queryForObject("select id from user_ where guid = ?", new Object[]{user.guid()}, Integer.class);
//insert privileges
for (final Privilege privilege : user.privileges()) {
this.jdbcTemplate.update("insert into user_privilege(user_id, privilege) values (?,?)", ps -> {
ps.setInt(1, id);
ps.setString(2, privilege.name());
});
}
}
@Override
public void updateUser(final User user) {
final String sql = " update user_ set username = ?, password = ?, phone = ?,email = ? where guid = ? ";
this.jdbcTemplate.update(sql, ps -> {
ps.setString(1, user.username());
ps.setString(2, user.password());
ps.setString(3, user.phone());
ps.setString(4, user.email());
ps.setString(5, user.guid());
});
}
@Override
public User findByUsername(String username) {
final String sql = " select * from user_ where username = ? and archived = 0 ";
final List<User> list = this.jdbcTemplate.query(sql, new Object[]{username}, userRowMapper);
User user = null;
if (!list.isEmpty()) {
user = list.get(0);
user.privileges().addAll(findPrivileges(user.id()));
}
return user;
}
@Override
public List<User> findUsersByUsername(String username) {
String sql = " select * from user_ where archived = 0 ";
Object[] params = new Object[]{};
if (StringUtils.isNotEmpty(username)) {
sql += " and username like ?";
params = new Object[]{"%" + username + "%"};
}
sql += " order by create_time desc ";
final List<User> list = this.jdbcTemplate.query(sql, params, userRowMapper);
for (User user : list) {
user.privileges().addAll(findPrivileges(user.id()));
}
return list;
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.user.User;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 2015/11/16
*
* @author Shengzhao Li
*/
public class UserRowMapper implements RowMapper<User> {
public UserRowMapper() {
}
@Override
public User mapRow(ResultSet rs, int i) throws SQLException {
User user = new User();
user.id(rs.getInt("id"));
user.guid(rs.getString("guid"));
user.archived(rs.getBoolean("archived"));
user.createTime(rs.getTimestamp("create_time").toLocalDateTime());
user.email(rs.getString("email"));
user.phone(rs.getString("phone"));
user.password(rs.getString("password"));
user.username(rs.getString("username"));
user.lastLoginTime(rs.getTimestamp("last_login_time"));
return user;
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.shared.BeanProvider;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.io.Serializable;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
public abstract class AbstractMongoSupport {
protected static final String ID = "_id";
private MongoTemplate mongoTemplate;
protected AbstractMongoSupport() {
}
protected MongoTemplate mongoTemplate() {
if (mongoTemplate == null) {
mongoTemplate = BeanProvider.getBean(MongoTemplate.class);
}
return mongoTemplate;
}
protected <T extends Serializable> T findById(Class<T> clazz, Object id) {
Query query = new Query(new Criteria(ID).is(id));
return this.mongoTemplate().findOne(query, clazz);
}
protected Query createIDQuery(Object id) {
final Criteria criteria = new Criteria(ID).is(id);
return new Query(criteria);
}
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.oauth.AccessToken;
import com.monkeyk.sos.domain.oauth.AccessTokenRepository;
import com.monkeyk.sos.domain.oauth.RefreshToken;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 2015/10/29
*
* @author Shengzhao Li
*/
@Repository("accessTokenRepositoryMongo")
public class AccessTokenRepositoryMongo extends AbstractMongoSupport implements AccessTokenRepository {
@Override
public void saveAccessToken(AccessToken accessToken) {
this.mongoTemplate().save(accessToken);
}
@Override
public AccessToken findAccessToken(String tokenId) {
return findById(AccessToken.class, tokenId);
}
@Override
public void removeAccessToken(String tokenId) {
final AccessToken accessToken = findAccessToken(tokenId);
this.mongoTemplate().remove(accessToken);
}
@Override
public void saveRefreshToken(RefreshToken refreshToken) {
this.mongoTemplate().save(refreshToken);
}
@Override
public RefreshToken findRefreshToken(String tokenId) {
return findById(RefreshToken.class, tokenId);
}
@Override
public void removeRefreshToken(String tokenId) {
final RefreshToken refreshToken = findRefreshToken(tokenId);
this.mongoTemplate().remove(refreshToken);
}
@Override
public void removeAccessTokenByRefreshToken(String refreshToken) {
final AccessToken accessToken = findAccessTokenByRefreshToken(refreshToken);
this.mongoTemplate().remove(accessToken);
}
@Override
public AccessToken findAccessTokenByRefreshToken(String refreshToken) {
Query query = new Query(new Criteria("refreshToken").is(refreshToken));
return this.mongoTemplate().findOne(query, AccessToken.class);
}
@Override
public AccessToken findAccessTokenByAuthenticationId(String authenticationId) {
Query query = new Query(new Criteria("authenticationId").is(authenticationId));
return this.mongoTemplate().findOne(query, AccessToken.class);
}
@Override
public List<AccessToken> findAccessTokensByUsername(String username) {
Query query = new Query(new Criteria("username").is(username));
return mongoTemplate().find(query, AccessToken.class);
}
@Override
public List<AccessToken> findAccessTokensByClientId(String clientId) {
Query query = new Query(new Criteria("clientId").is(clientId));
return mongoTemplate().find(query, AccessToken.class);
}
@Override
public List<AccessToken> findAccessTokensByClientIdAndUsername(String clientId, String userName) {
Query query = new Query(new Criteria("clientId").is(clientId));
query.addCriteria(new Criteria("username").is(userName));
return mongoTemplate().find(query, AccessToken.class);
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.oauth.AuthorizationCode;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import com.monkeyk.sos.domain.oauth.OauthRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
@Repository("oauthRepositoryMongo")
public class OauthRepositoryMongo extends AbstractMongoSupport implements OauthRepository {
private static final Logger LOG = LoggerFactory.getLogger(OauthRepositoryMongo.class);
@Override
public OauthClientDetails findOauthClientDetails(String clientId) {
LOG.debug("Call findOauthClientDetails, clientId = {}", clientId);
return findById(OauthClientDetails.class, clientId);
}
@Override
public List<OauthClientDetails> findAllOauthClientDetails() {
Query query = new Query();
query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
return this.mongoTemplate().find(query, OauthClientDetails.class);
}
@Override
public boolean updateOauthClientDetailsArchive(String clientId, boolean archive) {
LOG.debug("Call updateOauthClientDetailsArchive, clientId = {}, archive = {}", clientId, archive);
Update update = new Update();
update.set("archived", archive);
Query query = createIDQuery(clientId);
this.mongoTemplate().updateFirst(query, update, OauthClientDetails.class);
return true;
}
@Override
public void saveOauthClientDetails(OauthClientDetails clientDetails) {
this.mongoTemplate().insert(clientDetails);
}
@Override
public boolean removeOauthClientDetails(OauthClientDetails clientDetails) {
LOG.debug("Call removeOauthClientDetails, clientDetails = {}", clientDetails);
mongoTemplate().remove(clientDetails);
return true;
}
@Override
public void saveAuthorizationCode(AuthorizationCode authorizationCode) {
this.mongoTemplate().save(authorizationCode);
}
@Override
public AuthorizationCode removeAuthorizationCode(String code) {
final AuthorizationCode authorizationCode = findById(AuthorizationCode.class, code);
this.mongoTemplate().remove(authorizationCode);
return authorizationCode;
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.user.User;
import com.monkeyk.sos.domain.user.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
@Repository("userRepositoryMongo")
public class UserRepositoryMongo extends AbstractMongoSupport implements UserRepository {
private static final Logger LOG = LoggerFactory.getLogger(UserRepositoryMongo.class);
@Override
public User findByGuid(String guid) {
LOG.debug("Call findByGuid, guid = {}", guid);
return findById(User.class, guid);
}
@Override
public void saveUser(User user) {
this.mongoTemplate().insert(user);
}
@Override
public boolean updateUser(User user) {
Update update = new Update();
update.set("password", user.password())
.set("phone", user.phone())
.set("lastLoginTime", user.lastLoginTime())
.set("archived", user.archived())
.set("email", user.email());
update.set("privileges", user.privileges());
Query query = createIDQuery(user.guid());
this.mongoTemplate().updateFirst(query, update, User.class);
return true;
}
@Override
public User findByUsername(String username) {
LOG.debug("Call findByUsername, username = {}", username);
Query query = new Query(new Criteria("username").is(username));
return this.mongoTemplate().findOne(query, User.class);
}
@Override
public List<User> findAllUsers() {
Query query = new Query().with(new Sort(Sort.Direction.DESC, "createTime"));
return mongoTemplate().find(query, User.class);
}
@Override
public boolean removeUser(User user) {
LOG.debug("Call removeUser, user = {}", user);
mongoTemplate().remove(user);
return true;
}
@Override
public List<User> findUsersByUsername(String username) {
Query query = new Query(Criteria.where("username").is(username));
return mongoTemplate().find(query, User.class);
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.service.oauth;
/**
* 2015/11/9
*
* @author Shengzhao Li
*/
public interface ExtractTokenKeyDigester {
String digest(String tokenValue);
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.service.oauth;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 2015/11/9
*
* @author Shengzhao Li
*/
public class MD5ExtractTokenKeyDigester implements ExtractTokenKeyDigester {
public MD5ExtractTokenKeyDigester() {
}
@Override
public String digest(String value) {
if (value == null) {
return null;
}
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).");
}
try {
byte[] bytes = digest.digest(value.getBytes("UTF-8"));
return String.format("%032x", new BigInteger(1, bytes));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("UTF-8 encoding not available. Fatal (should be in the JDK).");
}
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.service.oauth;
import com.monkeyk.sos.domain.oauth.AuthorizationCode;
import com.monkeyk.sos.domain.oauth.OauthRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
import org.springframework.util.Assert;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
public class MongoAuthorizationCodeServices extends RandomValueAuthorizationCodeServices implements InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(MongoAuthorizationCodeServices.class);
private OauthRepository oauthRepository;
public MongoAuthorizationCodeServices() {
}
@Override
protected void store(String code, OAuth2Authentication authentication) {
AuthorizationCode authorizationCode = new AuthorizationCode()
.code(code).authentication(authentication);
oauthRepository.saveAuthorizationCode(authorizationCode);
LOG.debug("Store AuthorizationCode: {}", authorizationCode);
}
@Override
protected OAuth2Authentication remove(String code) {
AuthorizationCode authorizationCode = oauthRepository.removeAuthorizationCode(code);
LOG.debug("Remove AuthorizationCode: {}", authorizationCode);
return authorizationCode != null ? authorizationCode.authentication() : null;
}
public void setOauthRepository(OauthRepository oauthRepository) {
this.oauthRepository = oauthRepository;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(oauthRepository, "oauthRepository is null");
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.service.oauth;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import com.monkeyk.sos.domain.oauth.OauthRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.util.Assert;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
public class MongoClientDetailsService implements ClientDetailsService, InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(MongoClientDetailsService.class);
private OauthRepository oauthRepository;
public MongoClientDetailsService() {
}
@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
final OauthClientDetails oauthClientDetails = oauthRepository.findOauthClientDetails(clientId);
if (oauthClientDetails == null || oauthClientDetails.archived()) {
LOG.warn("Not found ClientDetails by clientId '{}', because null or archived", clientId);
throw new ClientRegistrationException("Not found ClientDetails by clientId '" + clientId + "', because null or archived");
}
return oauthClientDetails.toClientDetails();
}
public void setOauthRepository(OauthRepository oauthRepository) {
this.oauthRepository = oauthRepository;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(oauthRepository);
}
}

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.service.oauth;
import com.monkeyk.sos.domain.oauth.AccessToken;
import com.monkeyk.sos.domain.oauth.AccessTokenRepository;
import com.monkeyk.sos.domain.oauth.RefreshToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
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.util.Assert;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* 2015/10/28
*
* @author Shengzhao Li
*/
public class MongoTokenStore implements TokenStore, InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(MongoTokenStore.class);
private AccessTokenRepository tokenRepository;
private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
private ExtractTokenKeyDigester extractTokenKeyDigester = new MD5ExtractTokenKeyDigester();
public MongoTokenStore() {
}
@Override
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
final String authenticationId = authenticationKeyGenerator.extractKey(authentication);
OAuth2AccessToken accessToken = null;
try {
AccessToken token = tokenRepository.findAccessTokenByAuthenticationId(authenticationId);
accessToken = token != null ? token.token() : null;
} catch (IllegalArgumentException e) {
LOG.error("Could not extract access token for authentication {}", authentication);
}
if (accessToken != null
&& !authenticationId.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) {
removeAccessToken(accessToken.getValue());
// Keep the store consistent (maybe the same user is represented by this authentication but the details have
// changed)
storeAccessToken(accessToken, authentication);
}
return accessToken;
}
@Override
public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
LOG.debug("Call storeAccessToken, token = {}, authentication = {}", token, authentication);
String refreshToken = token.getRefreshToken() != null ? token.getRefreshToken().getValue() : null;
AccessToken accessToken = new AccessToken()
.tokenId(extractTokenKey(token.getValue()))
.token(token)
.authenticationId(authenticationKeyGenerator.extractKey(authentication))
.username(authentication.isClientOnly() ? null : authentication.getName())
.clientId(authentication.getOAuth2Request().getClientId())
.authentication(authentication)
.refreshToken(extractTokenKey(refreshToken));
tokenRepository.saveAccessToken(accessToken);
}
@Override
public OAuth2AccessToken readAccessToken(String tokenValue) {
LOG.debug("Call readAccessToken, tokenValue = {}", tokenValue);
OAuth2AccessToken token = null;
try {
final String tokenId = extractTokenKey(tokenValue);
final AccessToken accessToken = tokenRepository.findAccessToken(tokenId);
token = accessToken == null ? null : accessToken.token();
} catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize access token for {}", tokenValue);
removeAccessToken(tokenValue);
}
return token;
}
@Override
public void removeAccessToken(OAuth2AccessToken token) {
removeAccessToken(token.getValue());
}
@Override
public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
return readAuthentication(token.getValue());
}
@Override
public OAuth2Authentication readAuthentication(String token) {
LOG.debug("Call readAuthentication, token = {}", token);
OAuth2Authentication authentication = null;
try {
final String tokenId = extractTokenKey(token);
AccessToken accessToken = tokenRepository.findAccessToken(tokenId);
authentication = accessToken == null ? null : accessToken.authentication();
} catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize authentication for {}", token);
removeAccessToken(token);
}
return authentication;
}
protected void removeAccessToken(String tokenValue) {
final String tokenId = extractTokenKey(tokenValue);
tokenRepository.removeAccessToken(tokenId);
}
@Override
public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
LOG.debug("Call storeRefreshToken, refreshToken = {}, authentication = {}", refreshToken, authentication);
RefreshToken token = new RefreshToken()
.tokenId(extractTokenKey(refreshToken.getValue()))
.token(refreshToken)
.authentication(authentication);
tokenRepository.saveRefreshToken(token);
}
@Override
public OAuth2RefreshToken readRefreshToken(String tokenValue) {
LOG.debug("Call readRefreshToken, tokenValue = {}", tokenValue);
OAuth2RefreshToken refreshToken = null;
try {
final String tokenId = extractTokenKey(tokenValue);
RefreshToken refreshTokenFounded = tokenRepository.findRefreshToken(tokenId);
refreshToken = refreshTokenFounded == null ? null : refreshTokenFounded.token();
} catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize refresh token for token {}", tokenValue);
removeRefreshToken(tokenValue);
}
return refreshToken;
}
@Override
public void removeRefreshToken(OAuth2RefreshToken token) {
removeRefreshToken(token.getValue());
}
protected void removeRefreshToken(String token) {
final String tokenId = extractTokenKey(token);
tokenRepository.removeRefreshToken(tokenId);
}
@Override
public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
return readAuthenticationForRefreshToken(token.getValue());
}
protected OAuth2Authentication readAuthenticationForRefreshToken(String tokenValue) {
OAuth2Authentication authentication = null;
try {
final String tokenId = extractTokenKey(tokenValue);
RefreshToken refreshToken = tokenRepository.findRefreshToken(tokenId);
authentication = refreshToken == null ? null : refreshToken.authentication();
} catch (IllegalArgumentException e) {
LOG.warn("Failed to deserialize access token for {}", tokenValue);
removeRefreshToken(tokenValue);
}
return authentication;
}
@Override
public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
removeAccessTokenUsingRefreshToken(refreshToken.getValue());
}
protected void removeAccessTokenUsingRefreshToken(String refreshTokenValue) {
final String refreshToken = extractTokenKey(refreshTokenValue);
tokenRepository.removeAccessTokenByRefreshToken(refreshToken);
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
LOG.debug("Call findTokensByClientId, clientId = {}", clientId);
List<OAuth2AccessToken> accessTokens = new ArrayList<>();
List<AccessToken> tokenList = tokenRepository.findAccessTokensByClientId(clientId);
for (AccessToken token : tokenList) {
final OAuth2AccessToken accessToken = token.token();
if (accessToken != null) {
accessTokens.add(accessToken);
}
}
return accessTokens;
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
LOG.debug("Call findTokensByUserName, clientId = {}, username = {}", clientId, userName);
List<OAuth2AccessToken> accessTokens = new ArrayList<>();
List<AccessToken> tokenList = tokenRepository.findAccessTokensByClientIdAndUsername(clientId, userName);
for (AccessToken token : tokenList) {
final OAuth2AccessToken accessToken = token.token();
if (accessToken != null) {
accessTokens.add(accessToken);
}
}
return accessTokens;
}
protected String extractTokenKey(String value) {
return this.extractTokenKeyDigester.digest(value);
}
public void setTokenRepository(AccessTokenRepository tokenRepository) {
this.tokenRepository = tokenRepository;
}
public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
this.authenticationKeyGenerator = authenticationKeyGenerator;
}
public void setExtractTokenKeyDigester(ExtractTokenKeyDigester extractTokenKeyDigester) {
this.extractTokenKeyDigester = extractTokenKeyDigester;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(tokenRepository);
Assert.notNull(authenticationKeyGenerator);
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2013 Andaily Information Technology Co. Ltd
* www.andaily.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Andaily Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with Andaily Information Technology Co. Ltd.
*/
package com.monkeyk.sos.web;
import com.monkeyk.sos.domain.shared.BeanProvider;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
/**
* 15-6-22
*
* @author Shengzhao Li
*/
public class ExtContextLoaderListener extends ContextLoaderListener {
@Override
public void contextInitialized(ServletContextEvent event) {
super.contextInitialized(event);
final ServletContext servletContext = event.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
BeanProvider.initialize(applicationContext);
}
}

View File

@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import java.util.List;
import java.util.Set;
/**
* 2016/3/25
@ -38,7 +38,7 @@ public class UserFormDtoValidator implements Validator {
}
private void validatePrivileges(Errors errors, UserFormDto formDto) {
final List<Privilege> privileges = formDto.getPrivileges();
final Set<Privilege> privileges = formDto.getPrivileges();
if (privileges == null || privileges.isEmpty()) {
errors.rejectValue("privileges", null, "Privileges is required");
}

View File

@ -1,8 +1,11 @@
#JDBC configuration information
jdbc.driverClassName=com.mysql.jdbc.Driver
############
# localhost
############
jdbc.url=jdbc:mysql://localhost:3306/oauth2?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8
jdbc.username=andaily
jdbc.password=andaily
#MongoDB configuration
mongo.host=127.0.0.1
mongo.port=27017
# DB name
mongo.db=spring-oauth-server
# Username, password
mongo.username=mkk
mongo.password=mkk

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<!--annotation configuration -->
@ -21,30 +22,25 @@
</property>
</bean>
<!--dataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- MongoBD Database configuration host and port -->
<mongo:mongo host="${mongo.host}" port="${mongo.port}" id="mongodb">
<!--<mongo:options auto-connect-retry="true" connect-timeout="0"/>-->
</mongo:mongo>
<property name="validationQuery" value="SELECT 1"/>
<property name="testOnReturn" value="false"/>
<property name="testOnBorrow" value="true"/>
<!--Based on 100 connected user -->
<property name="maxActive" value="20"/>
<property name="maxIdle" value="5"/>
<!-- Define the mongoDbFactory with your database Name -->
<mongo:db-factory dbname="${mongo.db}" username="${mongo.username}" password="${mongo.password}"
id="mongoDbFactory"/>
<!-- Define the MongoTemplate -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<mongo:auditing/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Base package to scan the mongo repositories, where we create de DAOS to access data and domain objects -->
<!-- MongoRepository -->
<mongo:repositories base-package="com.monkeyk.sos.infrastructure.mongo"/>
</beans>

View File

@ -69,43 +69,23 @@
<oauth2:resource-server id="mobileResourceServer" resource-id="mobile-resource" token-services-ref="tokenServices"/>
<!--Config ClientDetailsService-->
<!--<oauth2:client-details-service id="clientDetailsService">-->
<!--&lt;!&ndash;unity client&ndash;&gt;-->
<!--<oauth2:client client-id="unity-client" resource-ids="unity-resource"-->
<!--authorized-grant-types="password,authorization_code,refresh_token,implicit"-->
<!--secret="unity" authorities="ROLE_UNITY" scope="read,write"/>-->
<!--&lt;!&ndash;mobile client&ndash;&gt;-->
<!--<oauth2:client client-id="mobile-client" resource-ids="mobile-resource"-->
<!--authorized-grant-types="password,authorization_code,refresh_token,implicit"-->
<!--secret="mobile" authorities="ROLE_MOBILE" scope="read,write"/>-->
<!--</oauth2:client-details-service>-->
<beans:bean id="clientDetailsService" class="com.monkeyk.sos.domain.oauth.CustomJdbcClientDetailsService">
<beans:constructor-arg index="0" ref="dataSource"/>
<beans:bean id="clientDetailsService" class="com.monkeyk.sos.service.oauth.MongoClientDetailsService">
<beans:property name="oauthRepository" ref="oauthRepositoryMongo"/>
</beans:bean>
<!--Config token services-->
<!--<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore"/>-->
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<beans:constructor-arg index="0" ref="dataSource"/>
<beans:bean id="tokenStore" class="com.monkeyk.sos.service.oauth.MongoTokenStore">
<beans:property name="tokenRepository" ref="accessTokenRepositoryMongo"/>
</beans:bean>
<beans:bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<beans:property name="tokenStore" ref="tokenStore"/>
<beans:property name="clientDetailsService" ref="clientDetailsService"/>
<beans:property name="supportRefreshToken" value="true"/>
</beans:bean>
<!--<global-method-security pre-post-annotations="enabled" proxy-target-class="true">-->
<!--<expression-handler ref="oauth2ExpressionHandler"/>-->
<!--</global-method-security>-->
<!--<oauth2:expression-handler id="oauth2ExpressionHandler"/>-->
<!--<oauth2:web-expression-handler id="oauth2WebExpressionHandler"/>-->
<beans:bean class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"
id="oAuth2RequestFactory">
@ -121,9 +101,8 @@
</beans:bean>
<beans:bean id="jdbcAuthorizationCodeServices"
class="org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices">
<beans:constructor-arg index="0" ref="dataSource"/>
<beans:bean id="authorizationCodeServices" class="com.monkeyk.sos.service.oauth.MongoAuthorizationCodeServices">
<beans:property name="oauthRepository" ref="oauthRepositoryMongo"/>
</beans:bean>
@ -131,7 +110,7 @@
user-approval-handler-ref="oauthUserApprovalHandler"
user-approval-page="oauth_approval"
error-page="oauth_error">
<oauth2:authorization-code authorization-code-services-ref="jdbcAuthorizationCodeServices"/>
<oauth2:authorization-code authorization-code-services-ref="authorizationCodeServices"/>
<oauth2:implicit/>
<oauth2:refresh-token/>
<oauth2:client-credentials/>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!--aop-->
<aop:config>
<aop:advisor advice-ref="applicationAdvisor" pointcut="execution(* com.monkeyk.sos.service.*.*(..))"/>
</aop:config>
<!--advisor-->
<tx:advice id="applicationAdvisor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
<tx:method name="load*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>

View File

@ -16,7 +16,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<link rel="shortcut icon" href="${contextPath}/resources/favicon.ico"/>
<title><decorator:title default=""/> - Spring Security&Oauth2</title>
<title><decorator:title default=""/> - Spring Security&Oauth2 [MongoDB]</title>
<link href="${contextPath}/resources/bootstrap.min.css" rel="stylesheet"/>
<decorator:head/>

View File

@ -5,12 +5,12 @@
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>spring-oauth-server</display-name>
<display-name>spring-oauth-server[mongodb]</display-name>
<distributable/>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>spring-oauth-server</param-value>
<param-value>spring-oauth-server[mongodb]</param-value>
</context-param>
<!--Encoding filter-->
@ -72,7 +72,7 @@
<!-- Spring context listener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<listener-class>com.monkeyk.sos.web.ExtContextLoaderListener</listener-class>
</listener>
<!--mvc-->

View File

@ -1,14 +1,14 @@
package com.monkeyk.sos;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.transaction.BeforeTransaction;
/**
* @author Shengzhao Li
*/
@ContextConfiguration(locations = {"classpath:/spring/*.xml"}, initializers = {TestApplicationContextInitializer.class})
public abstract class ContextTest extends AbstractTransactionalTestNGSpringContextTests {
public abstract class ContextTest extends AbstractTestNGSpringContextTests {
@BeforeTransaction
public void beforeTest() {

View File

@ -1,8 +1,7 @@
package com.monkeyk.sos.infrastructure;
import com.monkeyk.sos.ContextTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.data.mongodb.core.MongoTemplate;
/**
* @author Shengzhao Li
@ -10,13 +9,16 @@ import org.springframework.jdbc.core.JdbcTemplate;
public abstract class AbstractRepositoryTest extends ContextTest {
@Autowired
private JdbcTemplate jdbcTemplate;
private MongoTemplate mongoTemplate;
public JdbcTemplate jdbcTemplate() {
return jdbcTemplate;
//get MongoTemplate
protected MongoTemplate mongoTemplate() {
if (mongoTemplate == null) {
mongoTemplate = applicationContext.getBean(MongoTemplate.class);
}
return mongoTemplate;
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import com.monkeyk.sos.domain.oauth.OauthRepository;
import com.monkeyk.sos.domain.shared.GuidGenerator;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.List;
import static org.testng.Assert.*;
/*
* @author Shengzhao Li
*/
public class OauthRepositoryJdbcTest extends AbstractRepositoryTest {
@Autowired
private OauthRepository oauthRepositoryMyBatis;
@Test
public void findOauthClientDetails() {
OauthClientDetails oauthClientDetails = oauthRepositoryMyBatis.findOauthClientDetails("unity-client");
assertNull(oauthClientDetails);
}
@Test
public void saveOauthClientDetails() {
final String clientId = GuidGenerator.generate();
OauthClientDetails clientDetails = new OauthClientDetails().clientId(clientId);
oauthRepositoryMyBatis.saveOauthClientDetails(clientDetails);
final OauthClientDetails oauthClientDetails = oauthRepositoryMyBatis.findOauthClientDetails(clientId);
assertNotNull(oauthClientDetails);
assertNotNull(oauthClientDetails.clientId());
assertNull(oauthClientDetails.clientSecret());
}
@Test
public void findAllOauthClientDetails() {
final List<OauthClientDetails> allOauthClientDetails = oauthRepositoryMyBatis.findAllOauthClientDetails();
assertNotNull(allOauthClientDetails);
assertTrue(allOauthClientDetails.isEmpty());
}
@Test
public void updateOauthClientDetailsArchive() {
oauthRepositoryMyBatis.updateOauthClientDetailsArchive("ddooelddd", true);
}
}

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.jdbc;
import com.monkeyk.sos.domain.user.User;
import com.monkeyk.sos.domain.user.UserRepository;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.List;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertNull;
/*
* @author Shengzhao Li
*/
public class UserRepositoryJdbcTest extends AbstractRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void findByGuid() {
User user = userRepository.findByGuid("oood");
assertNull(user);
user = new User("user", "123", "123", "ewo@honyee.cc");
userRepository.saveUser(user);
user = userRepository.findByGuid(user.guid());
assertNotNull(user);
assertNotNull(user.email());
}
@Test
public void findUsersByUsername() {
User user = userRepository.findByGuid("oood");
assertNull(user);
user = new User("user", "123", "123", "ewo@honyee.cc");
userRepository.saveUser(user);
final List<User> list = userRepository.findUsersByUsername(user.username());
assertNotNull(list);
assertEquals(list.size(), 1);
}
@Test
public void updateUser() {
User user = new User("user", "123", "123", "ewo@honyee.cc");
userRepository.saveUser(user);
user = userRepository.findByGuid(user.guid());
assertNotNull(user);
assertNotNull(user.email());
String newEmail = "test@honyee.cc";
user.email(newEmail).phone("12344444");
userRepository.updateUser(user);
user = userRepository.findByGuid(user.guid());
assertNotNull(user);
assertEquals(user.email(), newEmail);
}
@Test
public void findByUsername() {
String username = "user";
User user = new User(username, "123", "123", "ewo@honyee.cc");
userRepository.saveUser(user);
User result = userRepository.findByUsername(username);
assertNotNull(result);
}
/*
* Run the test must initial db firstly
* */
@Test(enabled = false)
public void testPrivilege() {
String guid = "55b713df1c6f423e842ad68668523c49";
final User user = userRepository.findByGuid(guid);
assertNotNull(user);
assertEquals(user.privileges().size(), 1);
}
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.oauth.AccessToken;
import com.monkeyk.sos.domain.oauth.RefreshToken;
import com.monkeyk.sos.domain.shared.GuidGenerator;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import com.monkeyk.sos.infrastructure.DateUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
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.OAuth2Request;
import org.testng.annotations.Test;
import java.util.Date;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/*
* @author Shengzhao Li
*/
public class AccessTokenRepositoryMongoTest extends AbstractRepositoryTest {
private AccessTokenRepositoryMongo tokenRepositoryMongo;
private void prepTest() {
if (tokenRepositoryMongo == null) {
tokenRepositoryMongo = new AccessTokenRepositoryMongo();
tokenRepositoryMongo.setMongoTemplate(mongoTemplate());
}
}
@Test
public void removeAccessToken() {
prepTest();
String tokenId = GuidGenerator.generate();
final String refreshToken = GuidGenerator.generate();
OAuth2Request req = new OAuth2Request() {
};
Authentication userAu = new OAuth2Authentication(req, null);
OAuth2Authentication auth = new OAuth2Authentication(req, userAu);
OAuth2AccessToken tok = new DefaultOAuth2AccessToken(GuidGenerator.generate());
final String clientId = "client253";
final String username = "username1452";
final String authenticationId = GuidGenerator.generate();
AccessToken accessToken = new AccessToken()
.authentication(auth)
.token(tok)
.authenticationId(authenticationId)
.refreshToken(refreshToken)
.tokenId(tokenId).clientId(clientId).username(username);
tokenRepositoryMongo.saveAccessToken(accessToken);
final AccessToken token = tokenRepositoryMongo.findAccessToken(tokenId);
assertNotNull(token);
assertNotNull(token.createTime());
assertNotNull(token.clientId());
assertNotNull(token.authentication());
assertNotNull(token.token());
final AccessToken accessTokenByRefreshToken = tokenRepositoryMongo.findAccessTokenByRefreshToken(refreshToken);
assertNotNull(accessTokenByRefreshToken);
final List<AccessToken> list = tokenRepositoryMongo.findAccessTokensByClientId(clientId);
assertEquals(list.size(), 1);
final List<AccessToken> tokenList = tokenRepositoryMongo.findAccessTokensByUsername(username);
assertEquals(tokenList.size(), 1);
final AccessToken accessTokenByAuthenticationId = tokenRepositoryMongo.findAccessTokenByAuthenticationId(authenticationId);
assertNotNull(accessTokenByAuthenticationId);
tokenRepositoryMongo.removeAccessToken(token.tokenId());
}
@Test
public void removeRefreshToken() {
prepTest();
String tokenId = GuidGenerator.generate();
OAuth2Request req = new OAuth2Request() {
};
Authentication userAu = new OAuth2Authentication(req, null);
OAuth2Authentication auth = new OAuth2Authentication(req, userAu);
OAuth2RefreshToken toks = new DefaultExpiringOAuth2RefreshToken(GuidGenerator.generate(), new Date());
RefreshToken refreshToken = new RefreshToken()
.tokenId(tokenId).token(toks)
.authentication(auth);
tokenRepositoryMongo.saveRefreshToken(refreshToken);
final RefreshToken token = tokenRepositoryMongo.findRefreshToken(tokenId);
assertNotNull(token);
assertNotNull(token.tokenId());
assertNotNull(token.token());
assertNotNull(token.authentication());
tokenRepositoryMongo.removeRefreshToken(token.tokenId());
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.oauth.AuthorizationCode;
import com.monkeyk.sos.domain.oauth.OauthClientDetails;
import com.monkeyk.sos.domain.shared.GuidGenerator;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.testng.annotations.Test;
import java.util.List;
import static org.testng.Assert.*;
/*
* @author Shengzhao Li
*/
public class OauthRepositoryMongoTest extends AbstractRepositoryTest {
private OauthRepositoryMongo oauthRepositoryMongo;
private void prepTest() {
if (oauthRepositoryMongo == null) {
oauthRepositoryMongo = new OauthRepositoryMongo();
oauthRepositoryMongo.setMongoTemplate(mongoTemplate());
}
}
@Test
public void testFindOauthClientDetails() throws Exception {
prepTest();
final OauthClientDetails clientDetails = oauthRepositoryMongo.findOauthClientDetails("clientId");
assertNull(clientDetails);
}
@Test(enabled = false)
public void removeAuthorizationCode() throws Exception {
prepTest();
final String code = GuidGenerator.generate();
OAuth2Request request = new OAuth2Request() {
};
Authentication userAuth = new OAuth2Authentication(request, null);
OAuth2Authentication auth = new OAuth2Authentication(request, userAuth);
AuthorizationCode authorizationCode = new AuthorizationCode()
.code(code).authentication(auth);
final AuthorizationCode code1 = oauthRepositoryMongo.removeAuthorizationCode(code);
assertNull(code1);
oauthRepositoryMongo.saveAuthorizationCode(authorizationCode);
final AuthorizationCode code2 = oauthRepositoryMongo.removeAuthorizationCode(code);
assertNotNull(code2);
assertNotNull(code2.code());
assertNotNull(code2.authentication());
assertNotNull(code2.createTime());
}
@Test
public void findAllOauthClientDetails() throws Exception {
prepTest();
final List<OauthClientDetails> list = oauthRepositoryMongo.findAllOauthClientDetails();
assertNotNull(list);
assertTrue(list.isEmpty());
}
@Test
public void updateOauthClientDetailsArchive() throws Exception {
prepTest();
OauthClientDetails clientDetails = new OauthClientDetails();
clientDetails.clientId("test").clientSecret("secret");
oauthRepositoryMongo.saveOauthClientDetails(clientDetails);
final OauthClientDetails oauthClientDetails = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
assertNotNull(oauthClientDetails);
assertFalse(oauthClientDetails.archived());
oauthRepositoryMongo.updateOauthClientDetailsArchive(clientDetails.clientId(), true);
final OauthClientDetails details = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
assertNotNull(details);
assertTrue(details.archived());
}
@Test
public void saveOauthClientDetails() throws Exception {
prepTest();
OauthClientDetails clientDetails = new OauthClientDetails();
clientDetails.clientId("test").clientSecret("secret");
oauthRepositoryMongo.saveOauthClientDetails(clientDetails);
final OauthClientDetails oauthClientDetails = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
assertNotNull(oauthClientDetails);
final boolean b = oauthRepositoryMongo.removeOauthClientDetails(oauthClientDetails);
assertEquals(b, true);
final OauthClientDetails details = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
assertNull(details);
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
* www.monkeyk.com
* All rights reserved.
*
* This software is the confidential and proprietary information of
* MONKEYK Information Technology Co. Ltd ("Confidential Information").
* You shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement you
* entered into with MONKEYK Information Technology Co. Ltd.
*/
package com.monkeyk.sos.infrastructure.mongo;
import com.monkeyk.sos.domain.user.Privilege;
import com.monkeyk.sos.domain.user.User;
import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
import org.testng.annotations.Test;
import java.util.List;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
/*
* @author Shengzhao Li
*/
public class UserRepositoryMongoTest extends AbstractRepositoryTest {
private UserRepositoryMongo userRepository;
private void prepTest() {
if (userRepository == null) {
userRepository = new UserRepositoryMongo();
userRepository.setMongoTemplate(mongoTemplate());
}
}
@Test
public void testSaveUser() throws Exception {
prepTest();
User user = new User("user", "pass", "13302585", "ddedd@ddd.com");
user.privileges().add(Privilege.MOBILE);
userRepository.saveUser(user);
final User user1 = userRepository.findByGuid(user.guid());
assertNotNull(user1);
assertNotNull(user1.username());
assertNotNull(user1.createTime());
userRepository.removeUser(user1);
}
@Test
public void findByUsername() throws Exception {
prepTest();
User user = new User("user", "pass", "13302585", "ddedd@ddd.com");
user.privileges().add(Privilege.MOBILE);
userRepository.saveUser(user);
final User user1 = userRepository.findByUsername(user.username());
assertNotNull(user1);
assertNotNull(user1.username());
assertNotNull(user1.createTime());
userRepository.removeUser(user1);
}
@Test
public void findAllUsers() throws Exception {
prepTest();
final List<User> list = userRepository.findAllUsers();
assertNotNull(list);
assertTrue(list.isEmpty());
}
}

View File

@ -1,8 +1,11 @@
#JDBC configuration information
jdbc.driverClassName=com.mysql.jdbc.Driver
############
# localhost
############
jdbc.url=jdbc:mysql://localhost:3306/oauth2_test?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8
jdbc.username=andaily
jdbc.password=andaily
#MongoDB configuration
mongo.host=127.0.0.1
mongo.port=27017
# DB name
mongo.db=spring-oauth-server-test
# Username, password
mongo.username=mkk
mongo.password=mkk