diff --git a/docs/authn/social.md b/docs/authn/social.md index 5947f4e01..125993c33 100644 --- a/docs/authn/social.md +++ b/docs/authn/social.md @@ -40,7 +40,7 @@ config.socialsignon.sinaweibo.account.id=id config.socialsignon.sinaweibo.sortorder=1 -配置maxkey/spring/maxkey-support-social.xml +配置maxkey/spring/maxkey.xml
<bean id="socialSignOnWeibo" class="org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider">
diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/service/JdbcTicketServices.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/service/JdbcTicketServices.java
index 94f52cc34..8c113efe1 100644
--- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/service/JdbcTicketServices.java
+++ b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/ticket/service/JdbcTicketServices.java
@@ -3,9 +3,6 @@ package org.maxkey.authz.cas.endpoint.ticket.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
-
-import javax.sql.DataSource;
-
import org.maxkey.authz.cas.endpoint.ticket.Ticket;
import org.maxkey.util.SerializationUtils;
import org.springframework.dao.EmptyResultDataAccessException;
@@ -27,9 +24,9 @@ public class JdbcTicketServices extends RandomServiceTicketServices {
private final JdbcTemplate jdbcTemplate;
- public JdbcTicketServices(DataSource dataSource) {
- Assert.notNull(dataSource, "DataSource required");
- this.jdbcTemplate = new JdbcTemplate(dataSource);
+ public JdbcTicketServices(JdbcTemplate jdbcTemplate) {
+ Assert.notNull(jdbcTemplate, "jdbcTemplate required");
+ this.jdbcTemplate = jdbcTemplate;
}
@Override
diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java
index 71c2ba31b..1f21aa577 100644
--- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java
+++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/FormBasedAuthorizeEndpoint.java
@@ -73,7 +73,7 @@ public class FormBasedAuthorizeEndpoint extends AuthorizeBaseEndpoint{
modelAndView);
}
-
+ _logger.debug("FormBased View Name " + modelAndView.getViewName());
return modelAndView;
}
diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java
index 4db5bcfd6..2052b0232 100644
--- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java
+++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNetease163EmailAdapter.java
@@ -21,7 +21,7 @@ public class FormBasedNetease163EmailAdapter extends AbstractAuthorizeAdapter {
@Override
public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) {
- modelAndView.setViewName("authorize/formbased_netease_163email_sso_submint");
+ modelAndView.setViewName("authorize/formbased_163email_sso_submint");
AppsFormBasedDetails details=(AppsFormBasedDetails)app;
modelAndView.addObject("username", details.getAppUser().getRelatedUsername().substring(details.getAppUser().getRelatedUsername().indexOf("@")));
modelAndView.addObject("email", details.getAppUser().getRelatedUsername());
diff --git a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java
index dd2dbeebe..0d51aa3df 100644
--- a/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java
+++ b/maxkey-protocols/maxkey-protocol-formbased/src/main/java/org/maxkey/authz/formbased/endpoint/adapter/FormBasedNeteaseNoteYoudaoAdapter.java
@@ -23,7 +23,7 @@ public class FormBasedNeteaseNoteYoudaoAdapter extends AbstractAuthorizeAdapter
@Override
public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) {
- modelAndView.setViewName("authorize/formbased_netease_noteyoudao_sso_submint");
+ modelAndView.setViewName("authorize/formbased_wy_youdao_sso_submint");
AppsFormBasedDetails details=(AppsFormBasedDetails)app;
modelAndView.addObject("username", details.getAppUser().getRelatedUsername());
modelAndView.addObject("password", DigestUtils.md5Hex(details.getAppUser().getRelatedPassword()));
diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/code/JdbcAuthorizationCodeServices.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/code/JdbcAuthorizationCodeServices.java
index 676657d5e..cdfcc867f 100644
--- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/code/JdbcAuthorizationCodeServices.java
+++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/code/JdbcAuthorizationCodeServices.java
@@ -15,65 +15,70 @@ import org.springframework.jdbc.core.support.SqlLobValue;
import org.springframework.util.Assert;
/**
- * Implementation of authorization code services that stores the codes and authentication in a database.
+ * Implementation of authorization code services that stores the codes and
+ * authentication in a database.
*
* @author Crystal.Sea
*/
public class JdbcAuthorizationCodeServices extends RandomValueAuthorizationCodeServices {
- private static final String DEFAULT_SELECT_STATEMENT = "select code, authentication from oauth_code where code = ?";
- private static final String DEFAULT_INSERT_STATEMENT = "insert into oauth_code (code, authentication) values (?, ?)";
- private static final String DEFAULT_DELETE_STATEMENT = "delete from oauth_code where code = ?";
+ private static final String DEFAULT_SELECT_STATEMENT = "select code, authentication from oauth_code where code = ?";
+ private static final String DEFAULT_INSERT_STATEMENT = "insert into oauth_code (code, authentication) values (?, ?)";
+ private static final String DEFAULT_DELETE_STATEMENT = "delete from oauth_code where code = ?";
- private String selectAuthenticationSql = DEFAULT_SELECT_STATEMENT;
- private String insertAuthenticationSql = DEFAULT_INSERT_STATEMENT;
- private String deleteAuthenticationSql = DEFAULT_DELETE_STATEMENT;
+ private String selectAuthenticationSql = DEFAULT_SELECT_STATEMENT;
+ private String insertAuthenticationSql = DEFAULT_INSERT_STATEMENT;
+ private String deleteAuthenticationSql = DEFAULT_DELETE_STATEMENT;
- private final JdbcTemplate jdbcTemplate;
+ private final JdbcTemplate jdbcTemplate;
- public JdbcAuthorizationCodeServices(DataSource dataSource) {
- Assert.notNull(dataSource, "DataSource required");
- this.jdbcTemplate = new JdbcTemplate(dataSource);
- }
+ public JdbcAuthorizationCodeServices(DataSource dataSource) {
+ Assert.notNull(dataSource, "DataSource required");
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ }
- @Override
- protected void store(String code, OAuth2Authentication authentication) {
- jdbcTemplate.update(insertAuthenticationSql,
- new Object[] { code, new SqlLobValue(SerializationUtils.serialize(authentication)) }, new int[] {
- Types.VARCHAR, Types.BLOB });
- }
+ public JdbcAuthorizationCodeServices(JdbcTemplate jdbcTemplate) {
+ Assert.notNull(jdbcTemplate, "jdbcTemplate required");
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ @Override
+ protected void store(String code, OAuth2Authentication authentication) {
+ jdbcTemplate.update(insertAuthenticationSql,
+ new Object[] { code, new SqlLobValue(SerializationUtils.serialize(authentication)) },
+ new int[] { Types.VARCHAR, Types.BLOB });
+ }
- public OAuth2Authentication remove(String code) {
- OAuth2Authentication authentication;
+ public OAuth2Authentication remove(String code) {
+ OAuth2Authentication authentication;
- try {
- authentication = jdbcTemplate.queryForObject(selectAuthenticationSql,
- new RowMapper() {
- public OAuth2Authentication mapRow(ResultSet rs, int rowNum)
- throws SQLException {
- return SerializationUtils.deserialize(rs.getBytes("authentication"));
- }
- }, code);
- } catch (EmptyResultDataAccessException e) {
- return null;
- }
+ try {
+ authentication = jdbcTemplate.queryForObject(selectAuthenticationSql,
+ new RowMapper() {
+ public OAuth2Authentication mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return SerializationUtils.deserialize(rs.getBytes("authentication"));
+ }
+ }, code);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
- if (authentication != null) {
- jdbcTemplate.update(deleteAuthenticationSql, code);
- }
+ if (authentication != null) {
+ jdbcTemplate.update(deleteAuthenticationSql, code);
+ }
- return authentication;
- }
+ return authentication;
+ }
- public void setSelectAuthenticationSql(String selectAuthenticationSql) {
- this.selectAuthenticationSql = selectAuthenticationSql;
- }
+ public void setSelectAuthenticationSql(String selectAuthenticationSql) {
+ this.selectAuthenticationSql = selectAuthenticationSql;
+ }
- public void setInsertAuthenticationSql(String insertAuthenticationSql) {
- this.insertAuthenticationSql = insertAuthenticationSql;
- }
+ public void setInsertAuthenticationSql(String insertAuthenticationSql) {
+ this.insertAuthenticationSql = insertAuthenticationSql;
+ }
- public void setDeleteAuthenticationSql(String deleteAuthenticationSql) {
- this.deleteAuthenticationSql = deleteAuthenticationSql;
- }
+ public void setDeleteAuthenticationSql(String deleteAuthenticationSql) {
+ this.deleteAuthenticationSql = deleteAuthenticationSql;
+ }
}
diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JdbcTokenStore.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JdbcTokenStore.java
index 667b90318..6b1bbbd40 100644
--- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JdbcTokenStore.java
+++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JdbcTokenStore.java
@@ -37,423 +37,416 @@ import org.springframework.util.Assert;
*/
public class JdbcTokenStore implements TokenStore {
- private static final Log LOG = LogFactory.getLog(JdbcTokenStore.class);
+ private static final Log LOG = LogFactory.getLog(JdbcTokenStore.class);
- private static final String DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT = "insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)";
+ private static final String DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT = "insert into oauth_access_token (token_id, token, authentication_id, user_name, client_id, authentication, refresh_token) values (?, ?, ?, ?, ?, ?, ?)";
- private static final String DEFAULT_ACCESS_TOKEN_SELECT_STATEMENT = "select token_id, token from oauth_access_token where token_id = ?";
+ private static final String DEFAULT_ACCESS_TOKEN_SELECT_STATEMENT = "select token_id, token from oauth_access_token where token_id = ?";
- private static final String DEFAULT_ACCESS_TOKEN_AUTHENTICATION_SELECT_STATEMENT = "select token_id, authentication from oauth_access_token where token_id = ?";
+ private static final String DEFAULT_ACCESS_TOKEN_AUTHENTICATION_SELECT_STATEMENT = "select token_id, authentication from oauth_access_token where token_id = ?";
- private static final String DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT = "select token_id, token from oauth_access_token where authentication_id = ?";
+ private static final String DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT = "select token_id, token from oauth_access_token where authentication_id = ?";
- private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ? and client_id = ?";
+ private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ? and client_id = ?";
- private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ?";
-
- private static final String DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT = "select token_id, token from oauth_access_token where client_id = ?";
+ private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ?";
- private static final String DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT = "delete from oauth_access_token where token_id = ?";
+ private static final String DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT = "select token_id, token from oauth_access_token where client_id = ?";
- private static final String DEFAULT_ACCESS_TOKEN_DELETE_FROM_REFRESH_TOKEN_STATEMENT = "delete from oauth_access_token where refresh_token = ?";
+ private static final String DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT = "delete from oauth_access_token where token_id = ?";
- private static final String DEFAULT_REFRESH_TOKEN_INSERT_STATEMENT = "insert into oauth_refresh_token (token_id, token, authentication) values (?, ?, ?)";
+ private static final String DEFAULT_ACCESS_TOKEN_DELETE_FROM_REFRESH_TOKEN_STATEMENT = "delete from oauth_access_token where refresh_token = ?";
- private static final String DEFAULT_REFRESH_TOKEN_SELECT_STATEMENT = "select token_id, token from oauth_refresh_token where token_id = ?";
+ private static final String DEFAULT_REFRESH_TOKEN_INSERT_STATEMENT = "insert into oauth_refresh_token (token_id, token, authentication) values (?, ?, ?)";
- private static final String DEFAULT_REFRESH_TOKEN_AUTHENTICATION_SELECT_STATEMENT = "select token_id, authentication from oauth_refresh_token where token_id = ?";
+ private static final String DEFAULT_REFRESH_TOKEN_SELECT_STATEMENT = "select token_id, token from oauth_refresh_token where token_id = ?";
- private static final String DEFAULT_REFRESH_TOKEN_DELETE_STATEMENT = "delete from oauth_refresh_token where token_id = ?";
+ private static final String DEFAULT_REFRESH_TOKEN_AUTHENTICATION_SELECT_STATEMENT = "select token_id, authentication from oauth_refresh_token where token_id = ?";
- private String insertAccessTokenSql = DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT;
+ private static final String DEFAULT_REFRESH_TOKEN_DELETE_STATEMENT = "delete from oauth_refresh_token where token_id = ?";
- private String selectAccessTokenSql = DEFAULT_ACCESS_TOKEN_SELECT_STATEMENT;
+ private String insertAccessTokenSql = DEFAULT_ACCESS_TOKEN_INSERT_STATEMENT;
- private String selectAccessTokenAuthenticationSql = DEFAULT_ACCESS_TOKEN_AUTHENTICATION_SELECT_STATEMENT;
+ private String selectAccessTokenSql = DEFAULT_ACCESS_TOKEN_SELECT_STATEMENT;
- private String selectAccessTokenFromAuthenticationSql = DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT;
+ private String selectAccessTokenAuthenticationSql = DEFAULT_ACCESS_TOKEN_AUTHENTICATION_SELECT_STATEMENT;
- private String selectAccessTokensFromUserNameAndClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT;
+ private String selectAccessTokenFromAuthenticationSql = DEFAULT_ACCESS_TOKEN_FROM_AUTHENTICATION_SELECT_STATEMENT;
- private String selectAccessTokensFromUserNameSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT;
-
- private String selectAccessTokensFromClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT;
+ private String selectAccessTokensFromUserNameAndClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT;
- private String deleteAccessTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT;
+ private String selectAccessTokensFromUserNameSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT;
- private String insertRefreshTokenSql = DEFAULT_REFRESH_TOKEN_INSERT_STATEMENT;
+ private String selectAccessTokensFromClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT;
- private String selectRefreshTokenSql = DEFAULT_REFRESH_TOKEN_SELECT_STATEMENT;
+ private String deleteAccessTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT;
- private String selectRefreshTokenAuthenticationSql = DEFAULT_REFRESH_TOKEN_AUTHENTICATION_SELECT_STATEMENT;
+ private String insertRefreshTokenSql = DEFAULT_REFRESH_TOKEN_INSERT_STATEMENT;
- private String deleteRefreshTokenSql = DEFAULT_REFRESH_TOKEN_DELETE_STATEMENT;
+ private String selectRefreshTokenSql = DEFAULT_REFRESH_TOKEN_SELECT_STATEMENT;
- private String deleteAccessTokenFromRefreshTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_FROM_REFRESH_TOKEN_STATEMENT;
+ private String selectRefreshTokenAuthenticationSql = DEFAULT_REFRESH_TOKEN_AUTHENTICATION_SELECT_STATEMENT;
- private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
+ private String deleteRefreshTokenSql = DEFAULT_REFRESH_TOKEN_DELETE_STATEMENT;
- private final JdbcTemplate jdbcTemplate;
+ private String deleteAccessTokenFromRefreshTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_FROM_REFRESH_TOKEN_STATEMENT;
- public JdbcTokenStore(DataSource dataSource) {
- Assert.notNull(dataSource, "DataSource required");
- this.jdbcTemplate = new JdbcTemplate(dataSource);
- }
+ private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
- public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
- this.authenticationKeyGenerator = authenticationKeyGenerator;
- }
+ private final JdbcTemplate jdbcTemplate;
- public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
- OAuth2AccessToken accessToken = null;
-
- String key = authenticationKeyGenerator.extractKey(authentication);
- try {
- accessToken = jdbcTemplate.queryForObject(selectAccessTokenFromAuthenticationSql,
- new RowMapper() {
- public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
- return deserializeAccessToken(rs.getBytes(2));
- }
- }, key);
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.debug("Failed to find access token for authentication " + authentication);
- }
- }
- catch (IllegalArgumentException e) {
- LOG.error("Could not extract access token for authentication " + authentication, e);
- }
-
- if (accessToken != null
- && !key.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;
- }
-
- public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
- String refreshToken = null;
- if (token.getRefreshToken() != null) {
- refreshToken = token.getRefreshToken().getValue();
- }
-
- if (readAccessToken(token.getValue())!=null) {
- removeAccessToken(token.getValue());
- }
-
- jdbcTemplate.update(insertAccessTokenSql, new Object[] { extractTokenKey(token.getValue()),
- new SqlLobValue(serializeAccessToken(token)), authenticationKeyGenerator.extractKey(authentication),
- authentication.isClientOnly() ? null : authentication.getName(),
- authentication.getOAuth2Request().getClientId(),
- new SqlLobValue(serializeAuthentication(authentication)), extractTokenKey(refreshToken) }, new int[] {
- Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BLOB, Types.VARCHAR });
- }
-
- public OAuth2AccessToken readAccessToken(String tokenValue) {
- OAuth2AccessToken accessToken = null;
-
- try {
- accessToken = jdbcTemplate.queryForObject(selectAccessTokenSql, new RowMapper() {
- public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
- return deserializeAccessToken(rs.getBytes(2));
- }
- }, extractTokenKey(tokenValue));
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find access token for token " + tokenValue);
- }
- }
- catch (IllegalArgumentException e) {
- LOG.warn("Failed to deserialize access token for " + tokenValue, e);
- removeAccessToken(tokenValue);
- }
-
- return accessToken;
- }
-
- public void removeAccessToken(OAuth2AccessToken token) {
- removeAccessToken(token.getValue());
- }
-
- public void removeAccessToken(String tokenValue) {
- jdbcTemplate.update(deleteAccessTokenSql, extractTokenKey(tokenValue));
- }
-
- public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
- return readAuthentication(token.getValue());
- }
-
- public OAuth2Authentication readAuthentication(String token) {
- OAuth2Authentication authentication = null;
-
- try {
- authentication = jdbcTemplate.queryForObject(selectAccessTokenAuthenticationSql,
- new RowMapper() {
- public OAuth2Authentication mapRow(ResultSet rs, int rowNum) throws SQLException {
- return deserializeAuthentication(rs.getBytes(2));
- }
- }, extractTokenKey(token));
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find access token for token " + token);
- }
- }
- catch (IllegalArgumentException e) {
- LOG.warn("Failed to deserialize authentication for " + token, e);
- removeAccessToken(token);
- }
-
- return authentication;
- }
-
- public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
- jdbcTemplate.update(insertRefreshTokenSql, new Object[] { extractTokenKey(refreshToken.getValue()),
- new SqlLobValue(serializeRefreshToken(refreshToken)),
- new SqlLobValue(serializeAuthentication(authentication)) }, new int[] { Types.VARCHAR, Types.BLOB,
- Types.BLOB });
- }
-
- public OAuth2RefreshToken readRefreshToken(String token) {
- OAuth2RefreshToken refreshToken = null;
-
- try {
- refreshToken = jdbcTemplate.queryForObject(selectRefreshTokenSql, new RowMapper() {
- public OAuth2RefreshToken mapRow(ResultSet rs, int rowNum) throws SQLException {
- return deserializeRefreshToken(rs.getBytes(2));
- }
- }, extractTokenKey(token));
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find refresh token for token " + token);
- }
- }
- catch (IllegalArgumentException e) {
- LOG.warn("Failed to deserialize refresh token for token " + token, e);
- removeRefreshToken(token);
- }
-
- return refreshToken;
- }
-
- public void removeRefreshToken(OAuth2RefreshToken token) {
- removeRefreshToken(token.getValue());
- }
-
- public void removeRefreshToken(String token) {
- jdbcTemplate.update(deleteRefreshTokenSql, extractTokenKey(token));
- }
-
- public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
- return readAuthenticationForRefreshToken(token.getValue());
- }
-
- public OAuth2Authentication readAuthenticationForRefreshToken(String value) {
- OAuth2Authentication authentication = null;
-
- try {
- authentication = jdbcTemplate.queryForObject(selectRefreshTokenAuthenticationSql,
- new RowMapper() {
- public OAuth2Authentication mapRow(ResultSet rs, int rowNum) throws SQLException {
- return deserializeAuthentication(rs.getBytes(2));
- }
- }, extractTokenKey(value));
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find access token for token " + value);
- }
- }
- catch (IllegalArgumentException e) {
- LOG.warn("Failed to deserialize access token for " + value, e);
- removeRefreshToken(value);
- }
-
- return authentication;
- }
-
- public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
- removeAccessTokenUsingRefreshToken(refreshToken.getValue());
- }
-
- public void removeAccessTokenUsingRefreshToken(String refreshToken) {
- jdbcTemplate.update(deleteAccessTokenFromRefreshTokenSql, new Object[] { extractTokenKey(refreshToken) },
- new int[] { Types.VARCHAR });
- }
-
- public Collection findTokensByClientId(String clientId) {
- List accessTokens = new ArrayList();
-
- try {
- accessTokens = jdbcTemplate.query(selectAccessTokensFromClientIdSql, new SafeAccessTokenRowMapper(),
- clientId);
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find access token for clientId " + clientId);
- }
- }
- accessTokens = removeNulls(accessTokens);
-
- return accessTokens;
- }
-
- public Collection findTokensByUserName(String userName) {
- List accessTokens = new ArrayList();
-
- try {
- accessTokens = jdbcTemplate.query(selectAccessTokensFromUserNameSql, new SafeAccessTokenRowMapper(),
- userName);
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled())
- LOG.info("Failed to find access token for userName " + userName);
- }
- accessTokens = removeNulls(accessTokens);
-
- return accessTokens;
- }
-
- public Collection findTokensByClientIdAndUserName(String clientId, String userName) {
- List accessTokens = new ArrayList();
-
- try {
- accessTokens = jdbcTemplate.query(selectAccessTokensFromUserNameAndClientIdSql, new SafeAccessTokenRowMapper(),
- userName, clientId);
- }
- catch (EmptyResultDataAccessException e) {
- if (LOG.isInfoEnabled()) {
- LOG.info("Failed to find access token for clientId " + clientId + " and userName " + userName);
- }
- }
- accessTokens = removeNulls(accessTokens);
-
- return accessTokens;
- }
-
- private List removeNulls(List accessTokens) {
- List tokens = new ArrayList();
- for (OAuth2AccessToken token : accessTokens) {
- if (token != null) {
- tokens.add(token);
- }
- }
- return tokens;
- }
-
- protected String extractTokenKey(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).");
- }
- }
-
- private final class SafeAccessTokenRowMapper implements RowMapper {
- public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
- try {
- return deserializeAccessToken(rs.getBytes(2));
- }
- catch (IllegalArgumentException e) {
- String token = rs.getString(1);
- jdbcTemplate.update(deleteAccessTokenSql, token);
- return null;
- }
- }
- }
-
- protected byte[] serializeAccessToken(OAuth2AccessToken token) {
- return SerializationUtils.serialize(token);
- }
-
- protected byte[] serializeRefreshToken(OAuth2RefreshToken token) {
- return SerializationUtils.serialize(token);
- }
-
- protected byte[] serializeAuthentication(OAuth2Authentication authentication) {
- return SerializationUtils.serialize(authentication);
- }
-
- protected OAuth2AccessToken deserializeAccessToken(byte[] token) {
- return SerializationUtils.deserialize(token);
- }
-
- protected OAuth2RefreshToken deserializeRefreshToken(byte[] token) {
- return SerializationUtils.deserialize(token);
- }
-
- protected OAuth2Authentication deserializeAuthentication(byte[] authentication) {
- return SerializationUtils.deserialize(authentication);
- }
-
- public void setInsertAccessTokenSql(String insertAccessTokenSql) {
- this.insertAccessTokenSql = insertAccessTokenSql;
- }
-
- public void setSelectAccessTokenSql(String selectAccessTokenSql) {
- this.selectAccessTokenSql = selectAccessTokenSql;
- }
-
- public void setDeleteAccessTokenSql(String deleteAccessTokenSql) {
- this.deleteAccessTokenSql = deleteAccessTokenSql;
- }
-
- public void setInsertRefreshTokenSql(String insertRefreshTokenSql) {
- this.insertRefreshTokenSql = insertRefreshTokenSql;
- }
-
- public void setSelectRefreshTokenSql(String selectRefreshTokenSql) {
- this.selectRefreshTokenSql = selectRefreshTokenSql;
- }
-
- public void setDeleteRefreshTokenSql(String deleteRefreshTokenSql) {
- this.deleteRefreshTokenSql = deleteRefreshTokenSql;
- }
-
- public void setSelectAccessTokenAuthenticationSql(String selectAccessTokenAuthenticationSql) {
- this.selectAccessTokenAuthenticationSql = selectAccessTokenAuthenticationSql;
- }
-
- public void setSelectRefreshTokenAuthenticationSql(String selectRefreshTokenAuthenticationSql) {
- this.selectRefreshTokenAuthenticationSql = selectRefreshTokenAuthenticationSql;
- }
-
- public void setSelectAccessTokenFromAuthenticationSql(String selectAccessTokenFromAuthenticationSql) {
- this.selectAccessTokenFromAuthenticationSql = selectAccessTokenFromAuthenticationSql;
- }
-
- public void setDeleteAccessTokenFromRefreshTokenSql(String deleteAccessTokenFromRefreshTokenSql) {
- this.deleteAccessTokenFromRefreshTokenSql = deleteAccessTokenFromRefreshTokenSql;
- }
-
- public void setSelectAccessTokensFromUserNameSql(String selectAccessTokensFromUserNameSql) {
- this.selectAccessTokensFromUserNameSql = selectAccessTokensFromUserNameSql;
- }
-
- public void setSelectAccessTokensFromUserNameAndClientIdSql(String selectAccessTokensFromUserNameAndClientIdSql) {
- this.selectAccessTokensFromUserNameAndClientIdSql = selectAccessTokensFromUserNameAndClientIdSql;
- }
-
- public void setSelectAccessTokensFromClientIdSql(String selectAccessTokensFromClientIdSql) {
- this.selectAccessTokensFromClientIdSql = selectAccessTokensFromClientIdSql;
- }
+ public JdbcTokenStore(DataSource dataSource) {
+ Assert.notNull(dataSource, "DataSource required");
+ this.jdbcTemplate = new JdbcTemplate(dataSource);
+ }
+
+ public JdbcTokenStore(JdbcTemplate jdbcTemplate) {
+ Assert.notNull(jdbcTemplate, "jdbcTemplate required");
+ this.jdbcTemplate = jdbcTemplate;
+ }
+
+ public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
+ this.authenticationKeyGenerator = authenticationKeyGenerator;
+ }
+
+ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
+ OAuth2AccessToken accessToken = null;
+
+ String key = authenticationKeyGenerator.extractKey(authentication);
+ try {
+ accessToken = jdbcTemplate.queryForObject(selectAccessTokenFromAuthenticationSql,
+ new RowMapper() {
+ public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return deserializeAccessToken(rs.getBytes(2));
+ }
+ }, key);
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.debug("Failed to find access token for authentication " + authentication);
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.error("Could not extract access token for authentication " + authentication, e);
+ }
+
+ if (accessToken != null
+ && !key.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;
+ }
+
+ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
+ String refreshToken = null;
+ if (token.getRefreshToken() != null) {
+ refreshToken = token.getRefreshToken().getValue();
+ }
+
+ if (readAccessToken(token.getValue()) != null) {
+ removeAccessToken(token.getValue());
+ }
+
+ jdbcTemplate.update(insertAccessTokenSql,
+ new Object[] { extractTokenKey(token.getValue()), new SqlLobValue(serializeAccessToken(token)),
+ authenticationKeyGenerator.extractKey(authentication),
+ authentication.isClientOnly() ? null : authentication.getName(),
+ authentication.getOAuth2Request().getClientId(),
+ new SqlLobValue(serializeAuthentication(authentication)), extractTokenKey(refreshToken) },
+ new int[] { Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BLOB,
+ Types.VARCHAR });
+ }
+
+ public OAuth2AccessToken readAccessToken(String tokenValue) {
+ OAuth2AccessToken accessToken = null;
+
+ try {
+ accessToken = jdbcTemplate.queryForObject(selectAccessTokenSql, new RowMapper() {
+ public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return deserializeAccessToken(rs.getBytes(2));
+ }
+ }, extractTokenKey(tokenValue));
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find access token for token " + tokenValue);
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize access token for " + tokenValue, e);
+ removeAccessToken(tokenValue);
+ }
+
+ return accessToken;
+ }
+
+ public void removeAccessToken(OAuth2AccessToken token) {
+ removeAccessToken(token.getValue());
+ }
+
+ public void removeAccessToken(String tokenValue) {
+ jdbcTemplate.update(deleteAccessTokenSql, extractTokenKey(tokenValue));
+ }
+
+ public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
+ return readAuthentication(token.getValue());
+ }
+
+ public OAuth2Authentication readAuthentication(String token) {
+ OAuth2Authentication authentication = null;
+
+ try {
+ authentication = jdbcTemplate.queryForObject(selectAccessTokenAuthenticationSql,
+ new RowMapper() {
+ public OAuth2Authentication mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return deserializeAuthentication(rs.getBytes(2));
+ }
+ }, extractTokenKey(token));
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find access token for token " + token);
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize authentication for " + token, e);
+ removeAccessToken(token);
+ }
+
+ return authentication;
+ }
+
+ public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
+ jdbcTemplate.update(insertRefreshTokenSql,
+ new Object[] { extractTokenKey(refreshToken.getValue()),
+ new SqlLobValue(serializeRefreshToken(refreshToken)),
+ new SqlLobValue(serializeAuthentication(authentication)) },
+ new int[] { Types.VARCHAR, Types.BLOB, Types.BLOB });
+ }
+
+ public OAuth2RefreshToken readRefreshToken(String token) {
+ OAuth2RefreshToken refreshToken = null;
+
+ try {
+ refreshToken = jdbcTemplate.queryForObject(selectRefreshTokenSql, new RowMapper() {
+ public OAuth2RefreshToken mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return deserializeRefreshToken(rs.getBytes(2));
+ }
+ }, extractTokenKey(token));
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find refresh token for token " + token);
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize refresh token for token " + token, e);
+ removeRefreshToken(token);
+ }
+
+ return refreshToken;
+ }
+
+ public void removeRefreshToken(OAuth2RefreshToken token) {
+ removeRefreshToken(token.getValue());
+ }
+
+ public void removeRefreshToken(String token) {
+ jdbcTemplate.update(deleteRefreshTokenSql, extractTokenKey(token));
+ }
+
+ public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
+ return readAuthenticationForRefreshToken(token.getValue());
+ }
+
+ public OAuth2Authentication readAuthenticationForRefreshToken(String value) {
+ OAuth2Authentication authentication = null;
+
+ try {
+ authentication = jdbcTemplate.queryForObject(selectRefreshTokenAuthenticationSql,
+ new RowMapper() {
+ public OAuth2Authentication mapRow(ResultSet rs, int rowNum) throws SQLException {
+ return deserializeAuthentication(rs.getBytes(2));
+ }
+ }, extractTokenKey(value));
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find access token for token " + value);
+ }
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize access token for " + value, e);
+ removeRefreshToken(value);
+ }
+
+ return authentication;
+ }
+
+ public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
+ removeAccessTokenUsingRefreshToken(refreshToken.getValue());
+ }
+
+ public void removeAccessTokenUsingRefreshToken(String refreshToken) {
+ jdbcTemplate.update(deleteAccessTokenFromRefreshTokenSql, new Object[] { extractTokenKey(refreshToken) },
+ new int[] { Types.VARCHAR });
+ }
+
+ public Collection findTokensByClientId(String clientId) {
+ List accessTokens = new ArrayList();
+
+ try {
+ accessTokens = jdbcTemplate.query(selectAccessTokensFromClientIdSql, new SafeAccessTokenRowMapper(),
+ clientId);
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find access token for clientId " + clientId);
+ }
+ }
+ accessTokens = removeNulls(accessTokens);
+
+ return accessTokens;
+ }
+
+ public Collection findTokensByUserName(String userName) {
+ List accessTokens = new ArrayList();
+
+ try {
+ accessTokens = jdbcTemplate.query(selectAccessTokensFromUserNameSql, new SafeAccessTokenRowMapper(),
+ userName);
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled())
+ LOG.info("Failed to find access token for userName " + userName);
+ }
+ accessTokens = removeNulls(accessTokens);
+
+ return accessTokens;
+ }
+
+ public Collection findTokensByClientIdAndUserName(String clientId, String userName) {
+ List accessTokens = new ArrayList();
+
+ try {
+ accessTokens = jdbcTemplate.query(selectAccessTokensFromUserNameAndClientIdSql,
+ new SafeAccessTokenRowMapper(), userName, clientId);
+ } catch (EmptyResultDataAccessException e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Failed to find access token for clientId " + clientId + " and userName " + userName);
+ }
+ }
+ accessTokens = removeNulls(accessTokens);
+
+ return accessTokens;
+ }
+
+ private List removeNulls(List accessTokens) {
+ List tokens = new ArrayList();
+ for (OAuth2AccessToken token : accessTokens) {
+ if (token != null) {
+ tokens.add(token);
+ }
+ }
+ return tokens;
+ }
+
+ protected String extractTokenKey(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).");
+ }
+ }
+
+ private final class SafeAccessTokenRowMapper implements RowMapper {
+ public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException {
+ try {
+ return deserializeAccessToken(rs.getBytes(2));
+ } catch (IllegalArgumentException e) {
+ String token = rs.getString(1);
+ jdbcTemplate.update(deleteAccessTokenSql, token);
+ return null;
+ }
+ }
+ }
+
+ protected byte[] serializeAccessToken(OAuth2AccessToken token) {
+ return SerializationUtils.serialize(token);
+ }
+
+ protected byte[] serializeRefreshToken(OAuth2RefreshToken token) {
+ return SerializationUtils.serialize(token);
+ }
+
+ protected byte[] serializeAuthentication(OAuth2Authentication authentication) {
+ return SerializationUtils.serialize(authentication);
+ }
+
+ protected OAuth2AccessToken deserializeAccessToken(byte[] token) {
+ return SerializationUtils.deserialize(token);
+ }
+
+ protected OAuth2RefreshToken deserializeRefreshToken(byte[] token) {
+ return SerializationUtils.deserialize(token);
+ }
+
+ protected OAuth2Authentication deserializeAuthentication(byte[] authentication) {
+ return SerializationUtils.deserialize(authentication);
+ }
+
+ public void setInsertAccessTokenSql(String insertAccessTokenSql) {
+ this.insertAccessTokenSql = insertAccessTokenSql;
+ }
+
+ public void setSelectAccessTokenSql(String selectAccessTokenSql) {
+ this.selectAccessTokenSql = selectAccessTokenSql;
+ }
+
+ public void setDeleteAccessTokenSql(String deleteAccessTokenSql) {
+ this.deleteAccessTokenSql = deleteAccessTokenSql;
+ }
+
+ public void setInsertRefreshTokenSql(String insertRefreshTokenSql) {
+ this.insertRefreshTokenSql = insertRefreshTokenSql;
+ }
+
+ public void setSelectRefreshTokenSql(String selectRefreshTokenSql) {
+ this.selectRefreshTokenSql = selectRefreshTokenSql;
+ }
+
+ public void setDeleteRefreshTokenSql(String deleteRefreshTokenSql) {
+ this.deleteRefreshTokenSql = deleteRefreshTokenSql;
+ }
+
+ public void setSelectAccessTokenAuthenticationSql(String selectAccessTokenAuthenticationSql) {
+ this.selectAccessTokenAuthenticationSql = selectAccessTokenAuthenticationSql;
+ }
+
+ public void setSelectRefreshTokenAuthenticationSql(String selectRefreshTokenAuthenticationSql) {
+ this.selectRefreshTokenAuthenticationSql = selectRefreshTokenAuthenticationSql;
+ }
+
+ public void setSelectAccessTokenFromAuthenticationSql(String selectAccessTokenFromAuthenticationSql) {
+ this.selectAccessTokenFromAuthenticationSql = selectAccessTokenFromAuthenticationSql;
+ }
+
+ public void setDeleteAccessTokenFromRefreshTokenSql(String deleteAccessTokenFromRefreshTokenSql) {
+ this.deleteAccessTokenFromRefreshTokenSql = deleteAccessTokenFromRefreshTokenSql;
+ }
+
+ public void setSelectAccessTokensFromUserNameSql(String selectAccessTokensFromUserNameSql) {
+ this.selectAccessTokensFromUserNameSql = selectAccessTokensFromUserNameSql;
+ }
+
+ public void setSelectAccessTokensFromUserNameAndClientIdSql(String selectAccessTokensFromUserNameAndClientIdSql) {
+ this.selectAccessTokensFromUserNameAndClientIdSql = selectAccessTokensFromUserNameAndClientIdSql;
+ }
+
+ public void setSelectAccessTokensFromClientIdSql(String selectAccessTokensFromClientIdSql) {
+ this.selectAccessTokensFromClientIdSql = selectAccessTokensFromClientIdSql;
+ }
}
diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JwtAccessTokenConverter.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JwtAccessTokenConverter.java
index 8b746bc30..ded111dd5 100644
--- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JwtAccessTokenConverter.java
+++ b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/token/store/JwtAccessTokenConverter.java
@@ -49,8 +49,9 @@ import org.springframework.security.crypto.codec.Base64;
import org.springframework.util.Assert;
/**
- * Helper that translates between JWT encoded token values and OAuth authentication information (in both directions).
- * Also acts as a {@link TokenEnhancer} when tokens are granted.
+ * Helper that translates between JWT encoded token values and OAuth
+ * authentication information (in both directions). Also acts as a
+ * {@link TokenEnhancer} when tokens are granted.
*
* @see TokenEnhancer
* @see AccessTokenConverter
@@ -60,219 +61,218 @@ import org.springframework.util.Assert;
*/
public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConverter, InitializingBean {
- /**
- * Field name for token id.
- */
- public static final String TOKEN_ID = AccessTokenConverter.JTI;
+ /**
+ * Field name for token id.
+ */
+ public static final String TOKEN_ID = AccessTokenConverter.JTI;
- private static final Log logger = LogFactory.getLog(JwtAccessTokenConverter.class);
+ private static final Log logger = LogFactory.getLog(JwtAccessTokenConverter.class);
- private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
+ private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
- private JsonParser objectMapper = JsonParserFactory.create();
+ private JsonParser objectMapper = JsonParserFactory.create();
- private String verifierKey = new RandomValueStringGenerator().generate();
+ private String verifierKey = new RandomValueStringGenerator().generate();
- private Signer signer = new MacSigner(verifierKey);
+ private Signer signer = new MacSigner(verifierKey);
- private String signingKey = verifierKey;
+ private String signingKey = verifierKey;
- private SignatureVerifier verifier;
+ private SignatureVerifier verifier;
- /**
- * @param tokenConverter the tokenConverter to set
- */
- public void setAccessTokenConverter(AccessTokenConverter tokenConverter) {
- this.tokenConverter = tokenConverter;
- }
+ /**
+ * @param tokenConverter the tokenConverter to set
+ */
+ public void setAccessTokenConverter(AccessTokenConverter tokenConverter) {
+ this.tokenConverter = tokenConverter;
+ }
- /**
- * @return the tokenConverter in use
- */
- public AccessTokenConverter getAccessTokenConverter() {
- return tokenConverter;
- }
+ /**
+ * @return the tokenConverter in use
+ */
+ public AccessTokenConverter getAccessTokenConverter() {
+ return tokenConverter;
+ }
- @Override
- public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
- return tokenConverter.convertAccessToken(token, authentication);
- }
+ @Override
+ public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
+ return tokenConverter.convertAccessToken(token, authentication);
+ }
- @Override
- public OAuth2AccessToken extractAccessToken(String value, Map map) {
- return tokenConverter.extractAccessToken(value, map);
- }
+ @Override
+ public OAuth2AccessToken extractAccessToken(String value, Map map) {
+ return tokenConverter.extractAccessToken(value, map);
+ }
- @Override
- public OAuth2Authentication extractAuthentication(Map map) {
- return tokenConverter.extractAuthentication(map);
- }
+ @Override
+ public OAuth2Authentication extractAuthentication(Map map) {
+ return tokenConverter.extractAuthentication(map);
+ }
- /**
- * Get the verification key for the token signatures.
- *
- * @return the key used to verify tokens
- */
- public Map getKey() {
- Map result = new LinkedHashMap();
- result.put("alg", signer.algorithm());
- result.put("value", verifierKey);
- return result;
- }
+ /**
+ * Get the verification key for the token signatures.
+ *
+ * @return the key used to verify tokens
+ */
+ public Map getKey() {
+ Map result = new LinkedHashMap();
+ result.put("alg", signer.algorithm());
+ result.put("value", verifierKey);
+ return result;
+ }
- public void setKeyPair(KeyPair keyPair) {
- PrivateKey privateKey = keyPair.getPrivate();
- Assert.state(privateKey instanceof RSAPrivateKey, "KeyPair must be an RSA ");
- signer = new RsaSigner((RSAPrivateKey) privateKey);
- RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
- verifier = new RsaVerifier(publicKey);
- verifierKey = "-----BEGIN PUBLIC KEY-----\n" + new String(Base64.encode(publicKey.getEncoded())) + "\n-----END PUBLIC KEY-----";
- }
- /**
- * Sets the JWT signing key. It can be either a simple MAC key or an RSA key. RSA keys should be in OpenSSH format,
- * as produced by ssh-keygen.
- *
- * @param key the key to be used for signing JWTs.
- */
- public void setSigningKey(String key) {
- Assert.hasText(key);
- key = key.trim();
+ public void setKeyPair(KeyPair keyPair) {
+ PrivateKey privateKey = keyPair.getPrivate();
+ Assert.state(privateKey instanceof RSAPrivateKey, "KeyPair must be an RSA ");
+ signer = new RsaSigner((RSAPrivateKey) privateKey);
+ RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+ verifier = new RsaVerifier(publicKey);
+ verifierKey = "-----BEGIN PUBLIC KEY-----\n" + new String(Base64.encode(publicKey.getEncoded()))
+ + "\n-----END PUBLIC KEY-----";
+ }
- this.signingKey = key;
+ /**
+ * Sets the JWT signing key. It can be either a simple MAC key or an RSA key.
+ * RSA keys should be in OpenSSH format, as produced by ssh-keygen.
+ *
+ * @param key the key to be used for signing JWTs.
+ */
+ public void setSigningKey(String key) {
+ Assert.hasText(key);
+ key = key.trim();
- if (isPublic(key)) {
- signer = new RsaSigner(key);
- logger.info("Configured with RSA signing key");
- }
- else {
- // Assume it's a MAC key
- this.verifierKey = key;
- signer = new MacSigner(key);
- }
- }
+ this.signingKey = key;
- /**
- * @return true if the key has a public verifier
- */
- private boolean isPublic(String key) {
- return key.startsWith("-----BEGIN");
- }
-
- /**
- * @return true if the signing key is a public key
- */
- public boolean isPublic() {
- return signer instanceof RsaSigner;
- }
+ if (isPublic(key)) {
+ signer = new RsaSigner(key);
+ logger.info("Configured with RSA signing key");
+ } else {
+ // Assume it's a MAC key
+ this.verifierKey = key;
+ signer = new MacSigner(key);
+ }
+ }
- /**
- * The key used for verifying signatures produced by this class. This is not used but is returned from the endpoint
- * to allow resource servers to obtain the key.
- *
- * For an HMAC key it will be the same value as the signing key and does not need to be set. For and RSA key, it
- * should be set to the String representation of the public key, in a standard format (e.g. OpenSSH keys)
- *
- * @param key the signature verification key (typically an RSA public key)
- */
- public void setVerifierKey(String key) {
- this.verifierKey = key;
- try {
- new RsaSigner(verifierKey);
- throw new IllegalArgumentException("Private key cannot be set as verifierKey property");
- }
- catch (Exception expected) {
- // Expected
- }
- }
+ /**
+ * @return true if the key has a public verifier
+ */
+ private boolean isPublic(String key) {
+ return key.startsWith("-----BEGIN");
+ }
- public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
- DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken);
- Map info = new LinkedHashMap(accessToken.getAdditionalInformation());
- String tokenId = result.getValue();
- if (!info.containsKey(TOKEN_ID)) {
- info.put(TOKEN_ID, tokenId);
- }
- result.setAdditionalInformation(info);
- result.setValue(encode(result, authentication));
- OAuth2RefreshToken refreshToken = result.getRefreshToken();
- if (refreshToken != null) {
- DefaultOAuth2AccessToken encodedRefreshToken = new DefaultOAuth2AccessToken(accessToken);
- encodedRefreshToken.setValue(refreshToken.getValue());
- Map refreshTokenInfo = new LinkedHashMap(accessToken.getAdditionalInformation());
- refreshTokenInfo.put(TOKEN_ID, encodedRefreshToken.getValue());
- encodedRefreshToken.setAdditionalInformation(refreshTokenInfo);
- DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(encode(encodedRefreshToken, authentication));
- if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
- Date expiration = ((ExpiringOAuth2RefreshToken) refreshToken).getExpiration();
- encodedRefreshToken.setExpiration(expiration);
- token = new DefaultExpiringOAuth2RefreshToken(encode(encodedRefreshToken, authentication), expiration);
- }
- result.setRefreshToken(token);
- }
- return result;
- }
+ /**
+ * @return true if the signing key is a public key
+ */
+ public boolean isPublic() {
+ return signer instanceof RsaSigner;
+ }
- protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
- String content;
- try {
- content = objectMapper.formatMap(tokenConverter.convertAccessToken(accessToken, authentication));
- }
- catch (Exception e) {
- throw new IllegalStateException("Cannot convert access token to JSON", e);
- }
- String token = JwtHelper.encode(content, signer).getEncoded();
- return token;
- }
+ /**
+ * The key used for verifying signatures produced by this class. This is not
+ * used but is returned from the endpoint to allow resource servers to obtain
+ * the key.
+ *
+ * For an HMAC key it will be the same value as the signing key and does not
+ * need to be set. For and RSA key, it should be set to the String
+ * representation of the public key, in a standard format (e.g. OpenSSH keys)
+ *
+ * @param key the signature verification key (typically an RSA public key)
+ */
+ public void setVerifierKey(String key) {
+ this.verifierKey = key;
+ try {
+ new RsaSigner(verifierKey);
+ throw new IllegalArgumentException("Private key cannot be set as verifierKey property");
+ } catch (Exception expected) {
+ // Expected
+ }
+ }
- protected Map decode(String token) {
- try {
- Jwt jwt = JwtHelper.decodeAndVerify(token, verifier);
- String content = jwt.getClaims();
- Map map = objectMapper.parseMap(content);
- if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) {
- Integer intValue = (Integer) map.get(EXP);
- map.put(EXP, new Long(intValue));
- }
- return map;
- }
- catch (Exception e) {
- throw new InvalidTokenException("Cannot convert access token to JSON", e);
- }
- }
+ public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
+ DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken);
+ Map info = new LinkedHashMap(accessToken.getAdditionalInformation());
+ String tokenId = result.getValue();
+ if (!info.containsKey(TOKEN_ID)) {
+ info.put(TOKEN_ID, tokenId);
+ }
+ result.setAdditionalInformation(info);
+ result.setValue(encode(result, authentication));
+ OAuth2RefreshToken refreshToken = result.getRefreshToken();
+ if (refreshToken != null) {
+ DefaultOAuth2AccessToken encodedRefreshToken = new DefaultOAuth2AccessToken(accessToken);
+ encodedRefreshToken.setValue(refreshToken.getValue());
+ Map refreshTokenInfo = new LinkedHashMap(
+ accessToken.getAdditionalInformation());
+ refreshTokenInfo.put(TOKEN_ID, encodedRefreshToken.getValue());
+ encodedRefreshToken.setAdditionalInformation(refreshTokenInfo);
+ DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(
+ encode(encodedRefreshToken, authentication));
+ if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
+ Date expiration = ((ExpiringOAuth2RefreshToken) refreshToken).getExpiration();
+ encodedRefreshToken.setExpiration(expiration);
+ token = new DefaultExpiringOAuth2RefreshToken(encode(encodedRefreshToken, authentication), expiration);
+ }
+ result.setRefreshToken(token);
+ }
+ return result;
+ }
- public void afterPropertiesSet() throws Exception {
- // Check the signing and verification keys match
- if (signer instanceof RsaSigner) {
- RsaVerifier verifier;
- try {
- verifier = new RsaVerifier(verifierKey);
- }
- catch (Exception e) {
- logger.warn("Unable to create an RSA verifier from verifierKey");
- return;
- }
+ protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
+ String content;
+ try {
+ content = objectMapper.formatMap(tokenConverter.convertAccessToken(accessToken, authentication));
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot convert access token to JSON", e);
+ }
+ String token = JwtHelper.encode(content, signer).getEncoded();
+ return token;
+ }
- byte[] test = "test".getBytes();
- try {
- verifier.verify(test, signer.sign(test));
- logger.info("Signing and verification RSA keys match");
- }
- catch (InvalidSignatureException e) {
- logger.error("Signing and verification RSA keys do not match");
- }
- }
- else {
- // Avoid a race condition where setters are called in the wrong order. Use of == is intentional.
- Assert.state(this.signingKey == this.verifierKey,
- "For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key");
- }
- SignatureVerifier verifier = new MacSigner(verifierKey);
- try {
- verifier = new RsaVerifier(verifierKey);
- }
- catch (Exception e) {
- logger.warn("Unable to create an RSA verifier from verifierKey");
- }
- this.verifier = verifier;
- }
+ protected Map decode(String token) {
+ try {
+ Jwt jwt = JwtHelper.decodeAndVerify(token, verifier);
+ String content = jwt.getClaims();
+ Map map = objectMapper.parseMap(content);
+ if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) {
+ Integer intValue = (Integer) map.get(EXP);
+ map.put(EXP, new Long(intValue));
+ }
+ return map;
+ } catch (Exception e) {
+ throw new InvalidTokenException("Cannot convert access token to JSON", e);
+ }
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ // Check the signing and verification keys match
+ if (signer instanceof RsaSigner) {
+ RsaVerifier verifier;
+ try {
+ verifier = new RsaVerifier(verifierKey);
+ } catch (Exception e) {
+ logger.warn("Unable to create an RSA verifier from verifierKey");
+ return;
+ }
+
+ byte[] test = "test".getBytes();
+ try {
+ verifier.verify(test, signer.sign(test));
+ logger.info("Signing and verification RSA keys match");
+ } catch (InvalidSignatureException e) {
+ logger.error("Signing and verification RSA keys do not match");
+ }
+ } else {
+ // Avoid a race condition where setters are called in the wrong order. Use of ==
+ // is intentional.
+ Assert.state(this.signingKey == this.verifierKey,
+ "For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key");
+ }
+ SignatureVerifier verifier = new MacSigner(verifierKey);
+ try {
+ verifier = new RsaVerifier(verifierKey);
+ } catch (Exception e) {
+ logger.warn("Unable to create an RSA verifier from verifierKey");
+ }
+ this.verifier = verifier;
+ }
}
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
index 8096349e6..0637d6e0d 100644
--- a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
@@ -34,7 +34,14 @@ import org.springframework.context.annotation.PropertySource;
"org.maxkey.domain.userinfo",
"org.maxkey.api.v1.contorller",
"org.maxkey.web.endpoint",
- "org.maxkey.web.contorller"
+ "org.maxkey.web.contorller",
+ //single sign on protocol
+ "org.maxkey.authz.endpoint",
+ "org.maxkey.authz.desktop.endpoint",
+ "org.maxkey.authz.exapi.endpoint",
+ "org.maxkey.authz.formbased.endpoint",
+ "org.maxkey.authz.ltpa.endpoint",
+ "org.maxkey.authz.token.endpoint",
})
public class MaxKeyConfig implements InitializingBean {
private static final Logger _logger = LoggerFactory.getLogger(MaxKeyConfig.class);
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/CasAutoConfiguration.java b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/CasAutoConfiguration.java
new file mode 100644
index 000000000..88d6332ae
--- /dev/null
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/CasAutoConfiguration.java
@@ -0,0 +1,58 @@
+package org.maxkey.autoconfigure;
+
+import org.maxkey.authz.cas.endpoint.ticket.service.InMemoryTicketServices;
+import org.maxkey.authz.cas.endpoint.ticket.service.JdbcTicketServices;
+import org.maxkey.authz.cas.endpoint.ticket.service.RedisTicketServices;
+import org.maxkey.authz.cas.endpoint.ticket.service.TicketServices;
+import org.maxkey.persistence.redis.RedisConnectionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@Configuration
+@ComponentScan(basePackages = {
+ "org.maxkey.authz.cas.endpoint"
+})
+@PropertySource("classpath:/application.properties")
+public class CasAutoConfiguration implements InitializingBean {
+ private static final Logger _logger = LoggerFactory.getLogger(CasAutoConfiguration.class);
+
+ /**
+ * TicketServices.
+ * @param persistence int
+ * @param validity int
+ * @return casTicketServices
+ */
+ @Bean(name = "casTicketServices")
+ public TicketServices casTicketServices(
+ @Value("${config.server.persistence}") int persistence,
+ @Value("${config.login.remeberme.validity}") int validity,
+ JdbcTemplate jdbcTemplate,
+ RedisConnectionFactory jedisConnectionFactory) {
+ TicketServices casTicketServices = null;
+ if (persistence == 0) {
+ casTicketServices = new InMemoryTicketServices();
+ _logger.debug("InMemoryTicketServices");
+ } else if (persistence == 1) {
+ casTicketServices = new JdbcTicketServices(jdbcTemplate);
+ _logger.debug("JdbcTicketServices");
+ } else if (persistence == 2) {
+ casTicketServices = new RedisTicketServices(jedisConnectionFactory);
+ _logger.debug("RedisTicketServices");
+ }
+ return casTicketServices;
+ }
+
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java
new file mode 100644
index 000000000..4c9536c5c
--- /dev/null
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java
@@ -0,0 +1,334 @@
+package org.maxkey.autoconfigure;
+
+import java.net.URI;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.sql.DataSource;
+
+import org.maxkey.authn.support.jwt.JwtLoginService;
+import org.maxkey.authz.oauth2.provider.ClientDetailsService;
+import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore;
+import org.maxkey.authz.oauth2.provider.approval.controller.OAuth20UserApprovalHandler;
+import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
+import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService;
+import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices;
+import org.maxkey.authz.oauth2.provider.code.InMemoryAuthorizationCodeServices;
+import org.maxkey.authz.oauth2.provider.code.JdbcAuthorizationCodeServices;
+import org.maxkey.authz.oauth2.provider.code.RedisAuthorizationCodeServices;
+import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestFactory;
+import org.maxkey.authz.oauth2.provider.token.TokenStore;
+import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
+import org.maxkey.authz.oauth2.provider.token.store.InMemoryTokenStore;
+import org.maxkey.authz.oauth2.provider.token.store.JdbcTokenStore;
+import org.maxkey.authz.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.maxkey.authz.oauth2.provider.token.store.RedisTokenStore;
+import org.maxkey.authz.oidc.idtoken.OIDCIdTokenEnhancer;
+import org.maxkey.config.oidc.OIDCProviderMetadataDetails;
+import org.maxkey.crypto.jose.keystore.JWKSetKeyStore;
+import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService;
+import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
+import org.maxkey.persistence.redis.RedisConnectionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWEAlgorithm;
+
+@Configuration
+@ComponentScan(basePackages = {
+ "org.maxkey.authz.oauth2.provider.endpoint",
+ "org.maxkey.authz.oauth2.provider.userinfo.endpoint",
+ "org.maxkey.authz.oauth2.provider.approval.controller"
+})
+@PropertySource("classpath:/application.properties")
+@PropertySource("classpath:/config/applicationConfig.properties")
+public class Oauth20AutoConfiguration implements InitializingBean {
+ private static final Logger _logger = LoggerFactory.getLogger(Oauth20AutoConfiguration.class);
+
+ /**
+ * OIDCProviderMetadataDetails.
+ * Self-issued Provider Metadata
+ * http://openid.net/specs/openid-connect-core-1_0.html#SelfIssued
+ */
+ @Bean(name = "oidcProviderMetadata")
+ public OIDCProviderMetadataDetails OIDCProviderMetadataDetails(
+ @Value("${config.oidc.metadata.issuer}")
+ String issuer,
+ @Value("${config.oidc.metadata.authorizationEndpoint}")
+ URI authorizationEndpoint,
+ @Value("${config.oidc.metadata.tokenEndpoint}")
+ URI tokenEndpoint,
+ @Value("${config.oidc.metadata.userinfoEndpoint}")
+ URI userinfoEndpoint) {
+ _logger.debug("RedisConnectionFactory init .");
+ OIDCProviderMetadataDetails oidcProviderMetadata = new OIDCProviderMetadataDetails();
+ oidcProviderMetadata.setIssuer(issuer);
+ oidcProviderMetadata.setAuthorizationEndpoint(authorizationEndpoint);
+ oidcProviderMetadata.setTokenEndpoint(tokenEndpoint);
+ oidcProviderMetadata.setUserinfoEndpoint(userinfoEndpoint);
+ return oidcProviderMetadata;
+ }
+
+ /**
+ * jwtSetKeyStore.
+ * @return
+ */
+ @Bean(name = "jwkSetKeyStore")
+ public JWKSetKeyStore jwtSetKeyStore() {
+ JWKSetKeyStore jwkSetKeyStore = new JWKSetKeyStore();
+ ClassPathResource classPathResource = new ClassPathResource("/config/keystore.jwks");
+ jwkSetKeyStore.setLocation(classPathResource);
+ return jwkSetKeyStore;
+ }
+
+ /**
+ * jwtSetKeyStore.
+ * @return
+ * @throws JOSEException
+ * @throws InvalidKeySpecException
+ * @throws NoSuchAlgorithmException
+ */
+ @Bean(name = "jwtSignerValidationService")
+ public DefaultJwtSigningAndValidationService jwtSignerValidationService(
+ JWKSetKeyStore jwtSetKeyStore)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
+ DefaultJwtSigningAndValidationService jwtSignerValidationService =
+ new DefaultJwtSigningAndValidationService(jwtSetKeyStore);
+ jwtSignerValidationService.setDefaultSignerKeyId("maxkey_rsa");
+ jwtSignerValidationService.setDefaultSigningAlgorithmName("RS256");
+ return jwtSignerValidationService;
+ }
+
+ /**
+ * jwtSetKeyStore.
+ * @return
+ * @throws JOSEException
+ * @throws InvalidKeySpecException
+ * @throws NoSuchAlgorithmException
+ */
+ @Bean(name = "jwtEncryptionService")
+ public DefaultJwtEncryptionAndDecryptionService jwtEncryptionService(
+ JWKSetKeyStore jwtSetKeyStore)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, JOSEException {
+ DefaultJwtEncryptionAndDecryptionService jwtEncryptionService =
+ new DefaultJwtEncryptionAndDecryptionService(jwtSetKeyStore);
+ jwtEncryptionService.setDefaultAlgorithm(JWEAlgorithm.RSA1_5);//RSA1_5
+ jwtEncryptionService.setDefaultDecryptionKeyId("maxkey_rsa");
+ jwtEncryptionService.setDefaultEncryptionKeyId("maxkey_rsa");
+ return jwtEncryptionService;
+ }
+
+ /**
+ * JwtLoginService.
+ * @return
+ */
+ @Bean(name = "jwtLoginService")
+ public JwtLoginService jwtLoginService(
+ DefaultJwtSigningAndValidationService jwtSignerValidationService,
+ OIDCProviderMetadataDetails oidcProviderMetadata) {
+ JwtLoginService jwkSetKeyStore = new JwtLoginService();
+ jwkSetKeyStore.setJwtSignerValidationService(jwtSignerValidationService);
+ jwkSetKeyStore.setJwtProviderMetadata(oidcProviderMetadata);
+ return jwkSetKeyStore;
+ }
+
+
+ /**
+ * tokenEnhancer.
+ * @return
+ */
+ @Bean(name = "tokenEnhancer")
+ public OIDCIdTokenEnhancer tokenEnhancer(
+ DefaultJwtSigningAndValidationService jwtSignerValidationService,
+ DefaultJwtEncryptionAndDecryptionService jwtEncryptionService,
+ OIDCProviderMetadataDetails oidcProviderMetadata,
+ ClientDetailsService oauth20JdbcClientDetailsService) {
+ OIDCIdTokenEnhancer tokenEnhancer = new OIDCIdTokenEnhancer();
+ tokenEnhancer.setJwtSignerService(jwtSignerValidationService);
+ tokenEnhancer.setJwtEnDecryptionService(jwtEncryptionService);
+ tokenEnhancer.setClientDetailsService(oauth20JdbcClientDetailsService);
+ tokenEnhancer.setProviderMetadata(oidcProviderMetadata);
+ return tokenEnhancer;
+ }
+ //以上部分为了支持OpenID Connect 1.0
+
+
+ /**
+ * AuthorizationCodeServices.
+ * @param persistence int
+ * @return oauth20AuthorizationCodeServices
+ */
+ @Bean(name = "oauth20AuthorizationCodeServices")
+ public AuthorizationCodeServices oauth20AuthorizationCodeServices(
+ @Value("${config.server.persistence}") int persistence,
+ JdbcTemplate jdbcTemplate,
+ RedisConnectionFactory jedisConnectionFactory) {
+ AuthorizationCodeServices authorizationCodeServices = null;
+ if (persistence == 0) {
+ authorizationCodeServices = new InMemoryAuthorizationCodeServices();
+ _logger.debug("InMemoryAuthorizationCodeServices");
+ } else if (persistence == 1) {
+ authorizationCodeServices = new JdbcAuthorizationCodeServices(jdbcTemplate);
+ _logger.debug("JdbcAuthorizationCodeServices");
+ } else if (persistence == 2) {
+ authorizationCodeServices = new RedisAuthorizationCodeServices(jedisConnectionFactory);
+ _logger.debug("RedisAuthorizationCodeServices");
+ }
+ return authorizationCodeServices;
+ }
+
+ /**
+ * TokenStore.
+ * @param persistence int
+ * @return oauth20TokenStore
+ */
+ @Bean(name = "oauth20TokenStore")
+ public TokenStore oauth20TokenStore(
+ @Value("${config.server.persistence}") int persistence,
+ JdbcTemplate jdbcTemplate,
+ RedisConnectionFactory jedisConnectionFactory) {
+ TokenStore tokenStore = null;
+ if (persistence == 0) {
+ tokenStore = new InMemoryTokenStore();
+ _logger.debug("InMemoryTokenStore");
+ } else if (persistence == 1) {
+ tokenStore = new JdbcTokenStore(jdbcTemplate);
+ _logger.debug("JdbcTokenStore");
+ } else if (persistence == 2) {
+ tokenStore = new RedisTokenStore(jedisConnectionFactory);
+ _logger.debug("RedisTokenStore");
+ }
+ return tokenStore;
+ }
+
+ /**
+ * jwtAccessTokenConverter.
+ * @return converter
+ */
+ @Bean(name = "converter")
+ public JwtAccessTokenConverter jwtAccessTokenConverter() {
+ JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
+ return jwtAccessTokenConverter;
+ }
+
+ /**
+ * clientDetailsService.
+ * @return oauth20JdbcClientDetailsService
+ */
+ @Bean(name = "oauth20JdbcClientDetailsService")
+ public JdbcClientDetailsService clientDetailsService(DataSource dataSource,PasswordEncoder passwordReciprocal) {
+ JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
+ clientDetailsService.setPasswordEncoder(passwordReciprocal);
+ return clientDetailsService;
+ }
+
+ /**
+ * clientDetailsUserDetailsService.
+ * @return oauth20ClientDetailsUserService
+ */
+ @Bean(name = "oauth20ClientDetailsUserService")
+ public ClientDetailsUserDetailsService clientDetailsUserDetailsService(
+ JdbcClientDetailsService oauth20JdbcClientDetailsService,PasswordEncoder passwordReciprocal) {
+ ClientDetailsUserDetailsService cientDetailsUserDetailsService =
+ new ClientDetailsUserDetailsService(oauth20JdbcClientDetailsService);
+ cientDetailsUserDetailsService.setPasswordEncoder(passwordReciprocal);
+ return cientDetailsUserDetailsService;
+ }
+
+
+ /**
+ * clientDetailsUserDetailsService.
+ * @return oauth20TokenServices
+ */
+ @Bean(name = "oauth20TokenServices")
+ public DefaultTokenServices DefaultTokenServices(
+ JdbcClientDetailsService oauth20JdbcClientDetailsService,
+ TokenStore oauth20TokenStore,
+ OIDCIdTokenEnhancer tokenEnhancer) {
+ DefaultTokenServices tokenServices = new DefaultTokenServices();
+ tokenServices.setClientDetailsService(oauth20JdbcClientDetailsService);
+ tokenServices.setTokenEnhancer(tokenEnhancer);
+ tokenServices.setTokenStore(oauth20TokenStore);
+ tokenServices.setSupportRefreshToken(true);
+ return tokenServices;
+ }
+
+
+ /**
+ * TokenApprovalStore.
+ * @return oauth20ApprovalStore
+ */
+ @Bean(name = "oauth20ApprovalStore")
+ public TokenApprovalStore tokenApprovalStore(
+ TokenStore oauth20TokenStore) {
+ TokenApprovalStore tokenApprovalStore = new TokenApprovalStore();
+ tokenApprovalStore.setTokenStore(oauth20TokenStore);
+ return tokenApprovalStore;
+ }
+
+
+ /**
+ * OAuth2RequestFactory.
+ * @return oAuth2RequestFactory
+ */
+ @Bean(name = "oAuth2RequestFactory")
+ public DefaultOAuth2RequestFactory oauth2RequestFactory(
+ JdbcClientDetailsService oauth20JdbcClientDetailsService) {
+ DefaultOAuth2RequestFactory oauth2RequestFactory =
+ new DefaultOAuth2RequestFactory(oauth20JdbcClientDetailsService);
+ return oauth2RequestFactory;
+ }
+
+ /**
+ * OAuth20UserApprovalHandler.
+ * @return oauth20UserApprovalHandler
+ */
+ @Bean(name = "oauth20UserApprovalHandler")
+ public OAuth20UserApprovalHandler oauth20UserApprovalHandler(
+ JdbcClientDetailsService oauth20JdbcClientDetailsService,
+ DefaultOAuth2RequestFactory oAuth2RequestFactory,
+ TokenApprovalStore oauth20ApprovalStore
+ ) {
+ OAuth20UserApprovalHandler userApprovalHandler = new OAuth20UserApprovalHandler();
+ userApprovalHandler.setApprovalStore(oauth20ApprovalStore);
+ userApprovalHandler.setRequestFactory(oAuth2RequestFactory);
+ userApprovalHandler.setClientDetailsService(oauth20JdbcClientDetailsService);
+ return userApprovalHandler;
+ }
+
+ /**
+ * ProviderManager.
+ * @return oauth20ClientAuthenticationManager
+ */
+ @Bean(name = "oauth20ClientAuthenticationManager")
+ public ProviderManager oauth20ClientAuthenticationManager(
+ ClientDetailsUserDetailsService oauth20ClientDetailsUserService
+ ) {
+ DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider();
+ PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
+ daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
+ daoAuthenticationProvider.setUserDetailsService(oauth20ClientDetailsUserService);
+ ProviderManager clientAuthenticationManager = new ProviderManager(daoAuthenticationProvider);
+ return clientAuthenticationManager;
+ }
+
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Saml20AutoConfiguration.java b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Saml20AutoConfiguration.java
new file mode 100644
index 000000000..24e34894d
--- /dev/null
+++ b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Saml20AutoConfiguration.java
@@ -0,0 +1,322 @@
+package org.maxkey.autoconfigure;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.VelocityException;
+import org.maxkey.authz.saml.common.EndpointGenerator;
+import org.maxkey.authz.saml.service.IDService;
+import org.maxkey.authz.saml.service.TimeService;
+import org.maxkey.authz.saml20.binding.decoder.OpenHTTPPostDecoder;
+import org.maxkey.authz.saml20.binding.decoder.OpenHTTPPostSimpleSignDecoder;
+import org.maxkey.authz.saml20.binding.decoder.OpenHTTPRedirectDecoder;
+import org.maxkey.authz.saml20.binding.impl.ExtractPostBindingAdapter;
+import org.maxkey.authz.saml20.binding.impl.ExtractRedirectBindingAdapter;
+import org.maxkey.authz.saml20.binding.impl.PostBindingAdapter;
+import org.maxkey.authz.saml20.binding.impl.PostSimpleSignBindingAdapter;
+import org.maxkey.authz.saml20.provider.xml.AuthnResponseGenerator;
+import org.maxkey.authz.saml20.xml.SAML2ValidatorSuite;
+import org.maxkey.crypto.keystore.KeyStoreLoader;
+import org.maxkey.domain.Saml20Metadata;
+import org.opensaml.common.binding.security.IssueInstantRule;
+import org.opensaml.common.binding.security.MessageReplayRule;
+import org.opensaml.util.storage.MapBasedStorageService;
+import org.opensaml.util.storage.ReplayCache;
+import org.opensaml.xml.ConfigurationException;
+import org.opensaml.xml.parse.BasicParserPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.ui.velocity.VelocityEngineFactoryBean;
+
+@Configuration
+@ComponentScan(basePackages = {
+ "org.maxkey.authz.saml20.provider.endpoint",
+ "org.maxkey.authz.saml20.metadata.endpoint",
+})
+@PropertySource("classpath:/application.properties")
+@PropertySource("classpath:/config/applicationConfig.properties")
+public class Saml20AutoConfiguration implements InitializingBean {
+ private static final Logger _logger = LoggerFactory.getLogger(Saml20AutoConfiguration.class);
+
+ /**
+ * samlBootstrapInitializer.
+ * @return samlBootstrapInitializer
+ * @throws ConfigurationException
+ */
+ @Bean(name = "samlBootstrapInitializer")
+ public String samlBootstrapInitializer() throws ConfigurationException {
+ org.opensaml.DefaultBootstrap.bootstrap();
+ return "";
+ }
+
+ /**
+ * TimeService.
+ * @return timeService
+ */
+ @Bean(name = "timeService")
+ public TimeService TimeService() {
+ TimeService timeService = new TimeService();
+ return timeService;
+ }
+
+ /**
+ * IDService.
+ * @return idService
+ */
+ @Bean(name = "idService")
+ public IDService idService() {
+ IDService idService = new IDService();
+ return idService;
+ }
+
+ /**
+ * EndpointGenerator.
+ * @return endpointGenerator
+ */
+ @Bean(name = "endpointGenerator")
+ public EndpointGenerator endpointGenerator() {
+ EndpointGenerator generator = new EndpointGenerator();
+ return generator;
+ }
+
+ /**
+ * AuthnResponseGenerator.
+ * @return authnResponseGenerator
+ */
+ @Bean(name = "authnResponseGenerator")
+ public AuthnResponseGenerator authnResponseGenerator(TimeService timeService,IDService idService,
+ @Value("${config.saml.v20.idp.issuer}") String issuerEntityName) {
+ AuthnResponseGenerator generator = new AuthnResponseGenerator(issuerEntityName,timeService,idService);
+ return generator;
+ }
+
+ /**
+ * IssuerEntityName.
+ * @return issuerEntityName
+ */
+ @Bean(name = "issuerEntityName")
+ public String issuerEntityName(
+ @Value("${config.saml.v20.idp.issuer}") String issuerEntityName) {
+ return issuerEntityName;
+ }
+
+ /**
+ * Saml20Metadata.
+ * @return saml20Metadata
+ */
+ @Bean(name = "saml20Metadata")
+ public Saml20Metadata saml20Metadata(
+ @Value("${config.saml.v20.metadata.orgName}") String orgName,
+ @Value("${config.saml.v20.metadata.orgDisplayName}") String orgDisplayName,
+ @Value("${config.saml.v20.metadata.orgURL}") String orgURL,
+ @Value("${config.saml.v20.metadata.company}") String company,
+ @Value("${config.saml.v20.metadata.contactType}") String contactType,
+ @Value("${config.saml.v20.metadata.givenName}") String givenName,
+ @Value("${config.saml.v20.metadata.surName}") String surName,
+ @Value("${config.saml.v20.metadata.emailAddress}") String emailAddress,
+ @Value("${config.saml.v20.metadata.telephoneNumber}") String telephoneNumber) {
+ Saml20Metadata metadata = new Saml20Metadata();
+ metadata.setOrgName(orgName);
+ metadata.setOrgDisplayName(orgDisplayName);
+ metadata.setOrgURL(orgURL);
+ metadata.setCompany(company);
+ metadata.setContactType(contactType);
+ metadata.setGivenName(givenName);
+ metadata.setSurName(surName);
+ metadata.setEmailAddress(emailAddress);
+ metadata.setTelephoneNumber(telephoneNumber);
+ return metadata;
+ }
+
+ /**
+ * SAML2ValidatorSuite.
+ * @return samlValidaotrSuite
+ */
+ @Bean(name = "samlValidaotrSuite")
+ public SAML2ValidatorSuite validatorSuite() {
+ SAML2ValidatorSuite validatorSuite = new SAML2ValidatorSuite();
+ return validatorSuite;
+ }
+
+ /**
+ * MapBasedStorageService.
+ * @return mapBasedStorageService
+ */
+ @Bean(name = "mapBasedStorageService")
+ public MapBasedStorageService mapBasedStorageService() {
+ MapBasedStorageService mapBasedStorageService = new MapBasedStorageService();
+ return mapBasedStorageService;
+ }
+
+ /**
+ * VelocityEngineFactoryBean.
+ * @return velocityEngine
+ * @throws IOException
+ * @throws VelocityException
+ */
+ @Bean(name = "velocityEngine")
+ public VelocityEngine velocityEngine() throws VelocityException, IOException {
+ VelocityEngineFactoryBean factory = new VelocityEngineFactoryBean();
+ factory.setPreferFileSystemAccess(false);
+ Properties velocityProperties = new Properties();
+ velocityProperties.put("resource.loader", "classpath");
+ velocityProperties.put("classpath.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ factory.setVelocityProperties(velocityProperties);
+ return factory.createVelocityEngine();
+ }
+
+ /**
+ * ReplayCache.
+ * @return replayCache
+ */
+ @Bean(name = "replayCache")
+ public ReplayCache replayCache(MapBasedStorageService mapBasedStorageService,
+ @Value("${config.saml.v20.replay.cache.life.in.millis}") long duration) {
+ ReplayCache replayCache = new ReplayCache(mapBasedStorageService,duration);
+ return replayCache;
+ }
+
+ /**
+ * MessageReplayRule.
+ * @return messageReplayRule
+ */
+ @Bean(name = "messageReplayRule")
+ public MessageReplayRule messageReplayRule(ReplayCache replayCache) {
+ MessageReplayRule messageReplayRule = new MessageReplayRule(replayCache);
+ return messageReplayRule;
+ }
+
+ /**
+ * BasicParserPool.
+ * @return samlParserPool
+ */
+ @Bean(name = "samlParserPool")
+ public BasicParserPool samlParserPool(
+ @Value("${config.saml.v20.max.parser.pool.size}") int maxPoolSize) {
+ BasicParserPool samlParserPool = new BasicParserPool();
+ samlParserPool.setMaxPoolSize(maxPoolSize);
+ return samlParserPool;
+ }
+
+ /**
+ * IssueInstantRule.
+ * @return issueInstantRule
+ */
+ @Bean(name = "issueInstantRule")
+ public IssueInstantRule issueInstantRule(
+ @Value("${config.saml.v20.issue.instant.check.clock.skew.in.seconds}") int newClockSkew,
+ @Value("${config.saml.v20.issue.instant.check.validity.time.in.seconds}") int newExpires) {
+ IssueInstantRule decoder = new IssueInstantRule(newClockSkew,newExpires);
+ decoder.setRequiredRule(true);
+ return decoder;
+ }
+
+ /**
+ * OpenHTTPPostSimpleSignDecoder.
+ * @return openHTTPPostSimpleSignDecoder
+ */
+ @Bean(name = "openHTTPPostSimpleSignDecoder")
+ public OpenHTTPPostSimpleSignDecoder openHTTPPostSimpleSignDecoder(BasicParserPool samlParserPool,
+ @Value("${config.saml.v20.idp.receiver.endpoint}") String receiverEndpoint) {
+ OpenHTTPPostSimpleSignDecoder decoder = new OpenHTTPPostSimpleSignDecoder(samlParserPool);
+ decoder.setReceiverEndpoint(receiverEndpoint);
+ return decoder;
+ }
+
+ /**
+ * OpenHTTPPostDecoder.
+ * @return openHTTPPostDecoder
+ */
+ @Bean(name = "openHTTPPostDecoder")
+ public OpenHTTPPostDecoder openHTTPPostDecoder(BasicParserPool samlParserPool,
+ @Value("${config.saml.v20.idp.receiver.endpoint}") String receiverEndpoint) {
+ OpenHTTPPostDecoder decoder = new OpenHTTPPostDecoder(samlParserPool);
+ decoder.setReceiverEndpoint(receiverEndpoint);
+ return decoder;
+ }
+
+ /**
+ * OpenHTTPRedirectDecoder.
+ * @return openHTTPRedirectDecoder
+ */
+ @Bean(name = "openHTTPRedirectDecoder")
+ public OpenHTTPRedirectDecoder openHTTPRedirectDecoder(BasicParserPool samlParserPool,
+ @Value("${config.saml.v20.idp.receiver.endpoint}") String receiverEndpoint) {
+ OpenHTTPRedirectDecoder decoder = new OpenHTTPRedirectDecoder(samlParserPool);
+ decoder.setReceiverEndpoint(receiverEndpoint);
+ return decoder;
+ }
+
+ /**
+ * ExtractPostBindingAdapter.
+ * @return extractPostBindingAdapter
+ */
+ @Bean(name = "extractPostBindingAdapter")
+ public ExtractPostBindingAdapter extractPostBindingAdapter(OpenHTTPPostDecoder openHTTPPostDecoder,
+ KeyStoreLoader keyStoreLoader,IssueInstantRule issueInstantRule,MessageReplayRule messageReplayRule) {
+ ExtractPostBindingAdapter adapter = new ExtractPostBindingAdapter(openHTTPPostDecoder);
+ adapter.setIssueInstantRule(issueInstantRule);
+ adapter.setKeyStoreLoader(keyStoreLoader);
+ adapter.setMessageReplayRule(messageReplayRule);
+ return adapter;
+ }
+
+ /**
+ * ExtractRedirectBindingAdapter.
+ * @return extractRedirectBindingAdapter
+ */
+ @Bean(name = "extractRedirectBindingAdapter")
+ public ExtractRedirectBindingAdapter extractRedirectBindingAdapter(OpenHTTPRedirectDecoder openHTTPRedirectDecoder,
+ KeyStoreLoader keyStoreLoader,IssueInstantRule issueInstantRule,MessageReplayRule messageReplayRule) {
+ ExtractRedirectBindingAdapter adapter = new ExtractRedirectBindingAdapter(openHTTPRedirectDecoder);
+ adapter.setIssueInstantRule(issueInstantRule);
+ adapter.setKeyStoreLoader(keyStoreLoader);
+ adapter.setMessageReplayRule(messageReplayRule);
+ return adapter;
+ }
+
+
+ /**
+ * PostSimpleSignBindingAdapter.
+ * @return postSimpleSignBindingAdapter
+ */
+ @Bean(name = "postSimpleSignBindingAdapter")
+ public PostSimpleSignBindingAdapter postSimpleSignBindingAdapter(VelocityEngine velocityEngine,
+ @Value("${config.saml.v20.idp.issuer}") String issuerEntityName) {
+ PostSimpleSignBindingAdapter adapter = new PostSimpleSignBindingAdapter();
+ adapter.setVelocityEngine(velocityEngine);
+ adapter.setIssuerEntityName(issuerEntityName);
+ return adapter;
+ }
+
+ /**
+ * PostBindingAdapter.
+ * @return postBindingAdapter
+ */
+ @Bean(name = "postBindingAdapter")
+ public PostBindingAdapter postBindingAdapter(VelocityEngine velocityEngine,
+ @Value("${config.saml.v20.idp.issuer}") String issuerEntityName) {
+ PostBindingAdapter adapter = new PostBindingAdapter();
+ adapter.setVelocityEngine(velocityEngine);
+ adapter.setIssuerEntityName(issuerEntityName);
+ return adapter;
+ }
+
+
+
+
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/maxkey-web-maxkey/src/main/resources/META-INF/spring.factories b/maxkey-web-maxkey/src/main/resources/META-INF/spring.factories
index b375262a3..7f156f262 100644
--- a/maxkey-web-maxkey/src/main/resources/META-INF/spring.factories
+++ b/maxkey-web-maxkey/src/main/resources/META-INF/spring.factories
@@ -3,4 +3,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.maxkey.autoconfigure.ApplicationAutoConfiguration,\
org.maxkey.autoconfigure.MvcAutoConfiguration,\
org.maxkey.autoconfigure.KaptchaAutoConfiguration,\
-org.maxkey.autoconfigure.RedisAutoConfiguration
+org.maxkey.autoconfigure.RedisAutoConfiguration,\
+org.maxkey.autoconfigure.CasAutoConfiguration,\
+org.maxkey.autoconfigure.Oauth20AutoConfiguration,\
+org.maxkey.autoconfigure.Saml20AutoConfiguration
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-cas.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-cas.xml
deleted file mode 100644
index e322e2196..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-cas.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-oauth2.0.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-oauth2.0.xml
deleted file mode 100644
index fab754b10..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-oauth2.0.xml
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-saml.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-saml.xml
deleted file mode 100644
index 5a19b1664..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-protocol-saml.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- classpath
- org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-basic.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-basic.xml
deleted file mode 100644
index a8b46b9cc..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-basic.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-httpheader.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-httpheader.xml
deleted file mode 100644
index 2029460db..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-httpheader.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-kerberos.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-kerberos.xml
deleted file mode 100644
index 0466185f7..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-kerberos.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-social.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-social.xml
deleted file mode 100644
index eabfbbfc7..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-social.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-wsfederation.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-wsfederation.xml
deleted file mode 100644
index 473b8d5cc..000000000
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey-support-wsfederation.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- classpath:${config.support.wsfederation.signingCertificate}
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml b/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
index 1016124cc..2a9d24982 100644
--- a/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
+++ b/maxkey-web-maxkey/src/main/resources/spring/maxkey.xml
@@ -18,30 +18,160 @@
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+ -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -95,8 +225,6 @@
-
-
diff --git a/maxkey-web-maxkey/src/main/resources/templates/views/authorize/app_password_protected.ftl b/maxkey-web-maxkey/src/main/resources/templates/views/authorize/app_password_protected.ftl
index 5293069a9..650875ff4 100644
--- a/maxkey-web-maxkey/src/main/resources/templates/views/authorize/app_password_protected.ftl
+++ b/maxkey-web-maxkey/src/main/resources/templates/views/authorize/app_password_protected.ftl
@@ -1,18 +1,11 @@
-
- Second Protected
-
-
-
-
-
-
+ <#include "formbased_common.ftl">
-