Merge branch 'master' into authorization-api
Conflicts: openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java openid-connect-server-webapp/src/main/webapp/WEB-INF/application-context.xml openid-connect-server/src/main/java/org/mitre/discovery/web/DiscoveryEndpoint.java openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultIntrospectionAuthorizer.javapull/708/merge
commit
8352145d82
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.oauth2.introspectingfilter;
|
||||
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
@ -55,6 +53,8 @@ import com.google.gson.JsonObject;
|
|||
import com.google.gson.JsonParser;
|
||||
import com.nimbusds.jose.util.Base64;
|
||||
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
|
||||
|
||||
/**
|
||||
* This ResourceServerTokenServices implementation introspects incoming tokens at a
|
||||
* server's introspection endpoint URL and passes an Authentication object along
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client;
|
||||
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.PRIVATE_KEY;
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_JWT;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
|
@ -79,6 +75,10 @@ import com.nimbusds.jwt.PlainJWT;
|
|||
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.PRIVATE_KEY;
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_BASIC;
|
||||
import static org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod.SECRET_JWT;
|
||||
|
||||
/**
|
||||
* OpenID Connect Authentication Filter class
|
||||
*
|
||||
|
|
|
@ -19,13 +19,6 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.mitre.util.JsonUtils.getAsBoolean;
|
||||
import static org.mitre.util.JsonUtils.getAsEncryptionMethodList;
|
||||
import static org.mitre.util.JsonUtils.getAsJweAlgorithmList;
|
||||
import static org.mitre.util.JsonUtils.getAsJwsAlgorithmList;
|
||||
import static org.mitre.util.JsonUtils.getAsString;
|
||||
import static org.mitre.util.JsonUtils.getAsStringList;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -48,6 +41,13 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import static org.mitre.util.JsonUtils.getAsBoolean;
|
||||
import static org.mitre.util.JsonUtils.getAsEncryptionMethodList;
|
||||
import static org.mitre.util.JsonUtils.getAsJweAlgorithmList;
|
||||
import static org.mitre.util.JsonUtils.getAsJwsAlgorithmList;
|
||||
import static org.mitre.util.JsonUtils.getAsString;
|
||||
import static org.mitre.util.JsonUtils.getAsStringList;
|
||||
|
||||
/**
|
||||
*
|
||||
* Dynamically fetches OpenID Connect server configurations based on the issuer. Caches the server configurations.
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.oauth2.introspectingfilter;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
@ -29,6 +25,11 @@ import org.junit.Test;
|
|||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestOAuth2AccessTokenImpl {
|
||||
|
||||
private static String tokenString = "thisisatokenstring";
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -32,6 +27,12 @@ import org.mockito.Mock;
|
|||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -32,6 +27,12 @@ import org.mockito.Mock;
|
|||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -31,6 +28,10 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
@ -50,6 +46,10 @@ import com.nimbusds.jose.util.Base64URL;
|
|||
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -34,6 +28,13 @@ import org.mockito.Mock;
|
|||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -32,6 +26,13 @@ import org.mitre.openid.connect.config.ServerConfiguration;
|
|||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.client.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
|
@ -30,6 +26,11 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
|
|||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -33,11 +33,17 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|||
@Entity
|
||||
@Table(name = "authentication_holder")
|
||||
@NamedQueries ({
|
||||
@NamedQuery(name = "AuthenticationHolderEntity.getAll", query = "select a from AuthenticationHolderEntity a"),
|
||||
@NamedQuery(name = "AuthenticationHolderEntity.getUnusedAuthenticationHolders", query = "select a from AuthenticationHolderEntity a where a.id not in (select t.authenticationHolder.id from OAuth2AccessTokenEntity t) and a.id not in (select r.authenticationHolder.id from OAuth2RefreshTokenEntity r)")
|
||||
@NamedQuery(name = AuthenticationHolderEntity.QUERY_ALL, query = "select a from AuthenticationHolderEntity a"),
|
||||
@NamedQuery(name = AuthenticationHolderEntity.QUERY_GET_UNUSED, query = "select a from AuthenticationHolderEntity a where " +
|
||||
"a.id not in (select t.authenticationHolder.id from OAuth2AccessTokenEntity t) and " +
|
||||
"a.id not in (select r.authenticationHolder.id from OAuth2RefreshTokenEntity r) and " +
|
||||
"a.id not in (select c.authenticationHolder.id from AuthorizationCodeEntity c)")
|
||||
})
|
||||
public class AuthenticationHolderEntity {
|
||||
|
||||
public static final String QUERY_GET_UNUSED = "AuthenticationHolderEntity.getUnusedAuthenticationHolders";
|
||||
public static final String QUERY_ALL = "AuthenticationHolderEntity.getAll";
|
||||
|
||||
private Long id;
|
||||
|
||||
private OAuth2Authentication authentication;
|
||||
|
|
|
@ -16,19 +16,20 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.oauth2.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import javax.persistence.Temporal;
|
||||
|
||||
/**
|
||||
* Entity class for authorization codes
|
||||
|
@ -39,15 +40,23 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
|||
@Entity
|
||||
@Table(name = "authorization_code")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "AuthorizationCodeEntity.getByValue", query = "select a from AuthorizationCodeEntity a where a.code = :code")
|
||||
@NamedQuery(name = AuthorizationCodeEntity.QUERY_BY_VALUE, query = "select a from AuthorizationCodeEntity a where a.code = :code"),
|
||||
@NamedQuery(name = AuthorizationCodeEntity.QUERY_EXPIRATION_BY_DATE, query = "select a from AuthorizationCodeEntity a where a.expiration <= :" + AuthorizationCodeEntity.PARAM_DATE)
|
||||
})
|
||||
public class AuthorizationCodeEntity {
|
||||
|
||||
public static final String QUERY_BY_VALUE = "AuthorizationCodeEntity.getByValue";
|
||||
public static final String QUERY_EXPIRATION_BY_DATE = "AuthorizationCodeEntity.expirationByDate";
|
||||
|
||||
public static final String PARAM_DATE = "date";
|
||||
|
||||
private Long id;
|
||||
|
||||
private String code;
|
||||
|
||||
private OAuth2Authentication authentication;
|
||||
private AuthenticationHolderEntity authenticationHolder;
|
||||
|
||||
private Date expiration;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
|
@ -62,9 +71,10 @@ public class AuthorizationCodeEntity {
|
|||
* @param code the authorization code
|
||||
* @param authRequest the AuthoriztionRequestHolder associated with the original code request
|
||||
*/
|
||||
public AuthorizationCodeEntity(String code, OAuth2Authentication authRequest) {
|
||||
public AuthorizationCodeEntity(String code, AuthenticationHolderEntity authenticationHolder, Date expiration) {
|
||||
this.code = code;
|
||||
this.authentication = authRequest;
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,20 +111,30 @@ public class AuthorizationCodeEntity {
|
|||
}
|
||||
|
||||
/**
|
||||
* The authentication in place when this token was created.
|
||||
* @return the authentication
|
||||
*/
|
||||
@Lob
|
||||
@Basic(fetch=FetchType.EAGER)
|
||||
@Column(name="authentication")
|
||||
public OAuth2Authentication getAuthentication() {
|
||||
return authentication;
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "auth_holder_id")
|
||||
public AuthenticationHolderEntity getAuthenticationHolder() {
|
||||
return authenticationHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authentication the authentication to set
|
||||
*/
|
||||
public void setAuthentication(OAuth2Authentication authentication) {
|
||||
this.authentication = authentication;
|
||||
public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) {
|
||||
this.authenticationHolder = authenticationHolder;
|
||||
}
|
||||
|
||||
@Basic
|
||||
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
|
||||
@Column(name = "expiration")
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,14 +66,16 @@ import com.nimbusds.jose.JWSAlgorithm;
|
|||
@Entity
|
||||
@Table(name = "client_details")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "ClientDetailsEntity.findAll", query = "SELECT c FROM ClientDetailsEntity c"),
|
||||
@NamedQuery(name = "ClientDetailsEntity.getByClientId", query = "select c from ClientDetailsEntity c where c.clientId = :clientId")
|
||||
@NamedQuery(name = ClientDetailsEntity.QUERY_ALL, query = "SELECT c FROM ClientDetailsEntity c"),
|
||||
@NamedQuery(name = ClientDetailsEntity.QUERY_BY_CLIENT_ID, query = "select c from ClientDetailsEntity c where c.clientId = :" + ClientDetailsEntity.PARAM_CLIENT_ID)
|
||||
})
|
||||
public class ClientDetailsEntity implements ClientDetails {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String QUERY_BY_CLIENT_ID = "ClientDetailsEntity.getByClientId";
|
||||
public static final String QUERY_ALL = "ClientDetailsEntity.findAll";
|
||||
|
||||
public static final String PARAM_CLIENT_ID = "clientId";
|
||||
|
||||
private static final int DEFAULT_ID_TOKEN_VALIDITY_SECONDS = 600;
|
||||
|
||||
private static final long serialVersionUID = -1617727085733786296L;
|
||||
|
|
|
@ -61,13 +61,13 @@ import com.nimbusds.jwt.JWTParser;
|
|||
@Entity
|
||||
@Table(name = "access_token")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getAll", query = "select a from OAuth2AccessTokenEntity a"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getAllExpiredByDate", query = "select a from OAuth2AccessTokenEntity a where a.expiration <= :date"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getByRefreshToken", query = "select a from OAuth2AccessTokenEntity a where a.refreshToken = :refreshToken"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getByClient", query = "select a from OAuth2AccessTokenEntity a where a.client = :client"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getByAuthentication", query = "select a from OAuth2AccessTokenEntity a where a.authenticationHolder.authentication = :authentication"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getByIdToken", query = "select a from OAuth2AccessTokenEntity a where a.idToken = :idToken"),
|
||||
@NamedQuery(name = "OAuth2AccessTokenEntity.getByTokenValue", query = "select a from OAuth2AccessTokenEntity a where a.value = :tokenValue")
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_ALL, query = "select a from OAuth2AccessTokenEntity a"),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_EXPIRED_BY_DATE, query = "select a from OAuth2AccessTokenEntity a where a.expiration <= :" + OAuth2AccessTokenEntity.PARAM_DATE),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_REFRESH_TOKEN, query = "select a from OAuth2AccessTokenEntity a where a.refreshToken = :" + OAuth2AccessTokenEntity.PARAM_REFERSH_TOKEN),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_CLIENT, query = "select a from OAuth2AccessTokenEntity a where a.client = :" + OAuth2AccessTokenEntity.PARAM_CLIENT),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_AUTHENTICATION, query = "select a from OAuth2AccessTokenEntity a where a.authenticationHolder.authentication = :" + OAuth2AccessTokenEntity.PARAM_AUTHENTICATION),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_ID_TOKEN, query = "select a from OAuth2AccessTokenEntity a where a.idToken = :" + OAuth2AccessTokenEntity.PARAM_ID_TOKEN),
|
||||
@NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_TOKEN_VALUE, query = "select a from OAuth2AccessTokenEntity a where a.value = :" + OAuth2AccessTokenEntity.PARAM_TOKEN_VALUE)
|
||||
})
|
||||
@org.codehaus.jackson.map.annotate.JsonSerialize(using = OAuth2AccessTokenJackson1Serializer.class)
|
||||
@org.codehaus.jackson.map.annotate.JsonDeserialize(using = OAuth2AccessTokenJackson1Deserializer.class)
|
||||
|
@ -75,6 +75,21 @@ import com.nimbusds.jwt.JWTParser;
|
|||
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = OAuth2AccessTokenJackson2Deserializer.class)
|
||||
public class OAuth2AccessTokenEntity implements OAuth2AccessToken {
|
||||
|
||||
public static final String QUERY_BY_TOKEN_VALUE = "OAuth2AccessTokenEntity.getByTokenValue";
|
||||
public static final String QUERY_BY_ID_TOKEN = "OAuth2AccessTokenEntity.getByIdToken";
|
||||
public static final String QUERY_BY_AUTHENTICATION = "OAuth2AccessTokenEntity.getByAuthentication";
|
||||
public static final String QUERY_BY_CLIENT = "OAuth2AccessTokenEntity.getByClient";
|
||||
public static final String QUERY_BY_REFRESH_TOKEN = "OAuth2AccessTokenEntity.getByRefreshToken";
|
||||
public static final String QUERY_EXPIRED_BY_DATE = "OAuth2AccessTokenEntity.getAllExpiredByDate";
|
||||
public static final String QUERY_ALL = "OAuth2AccessTokenEntity.getAll";
|
||||
|
||||
public static final String PARAM_TOKEN_VALUE = "tokenValue";
|
||||
public static final String PARAM_ID_TOKEN = "idToken";
|
||||
public static final String PARAM_AUTHENTICATION = "authentication";
|
||||
public static final String PARAM_CLIENT = "client";
|
||||
public static final String PARAM_REFERSH_TOKEN = "refreshToken";
|
||||
public static final String PARAM_DATE = "date";
|
||||
|
||||
public static String ID_TOKEN_FIELD_NAME = "id_token";
|
||||
|
||||
private Long id;
|
||||
|
|
|
@ -49,14 +49,25 @@ import com.nimbusds.jwt.JWTParser;
|
|||
@Entity
|
||||
@Table(name = "refresh_token")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "OAuth2RefreshTokenEntity.getAll", query = "select r from OAuth2RefreshTokenEntity r"),
|
||||
@NamedQuery(name = "OAuth2RefreshTokenEntity.getAllExpiredByDate", query = "select r from OAuth2RefreshTokenEntity r where r.expiration <= :date"),
|
||||
@NamedQuery(name = "OAuth2RefreshTokenEntity.getByClient", query = "select r from OAuth2RefreshTokenEntity r where r.client = :client"),
|
||||
@NamedQuery(name = "OAuth2RefreshTokenEntity.getByTokenValue", query = "select r from OAuth2RefreshTokenEntity r where r.value = :tokenValue"),
|
||||
@NamedQuery(name = "OAuth2RefreshTokenEntity.getByAuthentication", query = "select r from OAuth2RefreshTokenEntity r where r.authenticationHolder.authentication = :authentication")
|
||||
@NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_ALL, query = "select r from OAuth2RefreshTokenEntity r"),
|
||||
@NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_EXPIRED_BY_DATE, query = "select r from OAuth2RefreshTokenEntity r where r.expiration <= :" + OAuth2RefreshTokenEntity.PARAM_DATE),
|
||||
@NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, query = "select r from OAuth2RefreshTokenEntity r where r.client = :" + OAuth2RefreshTokenEntity.PARAM_CLIENT),
|
||||
@NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_TOKEN_VALUE, query = "select r from OAuth2RefreshTokenEntity r where r.value = :" + OAuth2RefreshTokenEntity.PARAM_TOKEN_VALUE),
|
||||
@NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_AUTHENTICATION, query = "select r from OAuth2RefreshTokenEntity r where r.authenticationHolder.authentication = :" + OAuth2RefreshTokenEntity.PARAM_AUTHENTICATION)
|
||||
})
|
||||
public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken {
|
||||
|
||||
public static final String QUERY_BY_AUTHENTICATION = "OAuth2RefreshTokenEntity.getByAuthentication";
|
||||
public static final String QUERY_BY_TOKEN_VALUE = "OAuth2RefreshTokenEntity.getByTokenValue";
|
||||
public static final String QUERY_BY_CLIENT = "OAuth2RefreshTokenEntity.getByClient";
|
||||
public static final String QUERY_EXPIRED_BY_DATE = "OAuth2RefreshTokenEntity.getAllExpiredByDate";
|
||||
public static final String QUERY_ALL = "OAuth2RefreshTokenEntity.getAll";
|
||||
|
||||
public static final String PARAM_AUTHENTICATION = "authentication";
|
||||
public static final String PARAM_TOKEN_VALUE = "tokenValue";
|
||||
public static final String PARAM_CLIENT = "client";
|
||||
public static final String PARAM_DATE = "date";
|
||||
|
||||
private Long id;
|
||||
|
||||
private AuthenticationHolderEntity authenticationHolder;
|
||||
|
|
|
@ -37,11 +37,16 @@ import javax.persistence.Transient;
|
|||
@Entity
|
||||
@Table(name = "system_scope")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "SystemScope.findAll", query = "select s from SystemScope s ORDER BY s.id"),
|
||||
@NamedQuery(name = "SystemScope.getByValue", query = "select s from SystemScope s WHERE s.value = :value")
|
||||
@NamedQuery(name = SystemScope.QUERY_ALL, query = "select s from SystemScope s ORDER BY s.id"),
|
||||
@NamedQuery(name = SystemScope.QUERY_BY_VALUE, query = "select s from SystemScope s WHERE s.value = :" + SystemScope.PARAM_VALUE)
|
||||
})
|
||||
public class SystemScope {
|
||||
|
||||
public static final String QUERY_BY_VALUE = "SystemScope.getByValue";
|
||||
public static final String QUERY_ALL = "SystemScope.findAll";
|
||||
|
||||
public static final String PARAM_VALUE = "value";
|
||||
|
||||
private Long id;
|
||||
private String value; // scope value
|
||||
private String description; // human-readable description
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.mitre.oauth2.repository;
|
|||
import java.util.List;
|
||||
|
||||
import org.mitre.oauth2.model.AuthenticationHolderEntity;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
|
||||
public interface AuthenticationHolderRepository {
|
||||
public List<AuthenticationHolderEntity> getAll();
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.oauth2.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mitre.oauth2.model.AuthorizationCodeEntity;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
|
||||
/**
|
||||
* Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys.
|
||||
|
@ -37,12 +37,23 @@ public interface AuthorizationCodeRepository {
|
|||
public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode);
|
||||
|
||||
/**
|
||||
* Consume an authorization code.
|
||||
* Get an authorization code from the repository by value.
|
||||
*
|
||||
* @param code the authorization code value
|
||||
* @return the authentication associated with the code
|
||||
* @throws InvalidGrantException if no AuthorizationCodeEntity is found with the given value
|
||||
*/
|
||||
public OAuth2Authentication consume(String code) throws InvalidGrantException;
|
||||
public AuthorizationCodeEntity getByCode(String code);
|
||||
|
||||
/**
|
||||
* Remove an authorization code from the repository
|
||||
*
|
||||
* @param authorizationCodeEntity
|
||||
*/
|
||||
public void remove(AuthorizationCodeEntity authorizationCodeEntity);
|
||||
|
||||
/**
|
||||
* @return A collection of all expired codes.
|
||||
*/
|
||||
public Collection<AuthorizationCodeEntity> getExpiredCodes();
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import com.google.common.collect.Sets;
|
|||
public interface SystemScopeService {
|
||||
|
||||
public static final String OFFLINE_ACCESS = "offline_access";
|
||||
public static final Object OPENID_SCOPE = "openid";
|
||||
public static final String OPENID_SCOPE = "openid";
|
||||
public static final String ID_TOKEN_SCOPE = "id-token"; // ID tokens are generated using this scope
|
||||
public static final String REGISTRATION_TOKEN_SCOPE = "registration-token"; // this scope manages dynamic client registrations
|
||||
public static final String RESOURCE_TOKEN_SCOPE = "resource-token"; // this scope manages client-style protected resources
|
||||
|
|
|
@ -20,6 +20,19 @@
|
|||
package org.mitre.openid.connect;
|
||||
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
|
||||
import org.mitre.oauth2.model.RegisteredClient;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import static org.mitre.oauth2.model.RegisteredClientFields.APPLICATION_TYPE;
|
||||
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID;
|
||||
import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID_ISSUED_AT;
|
||||
|
@ -64,19 +77,6 @@ import static org.mitre.util.JsonUtils.getAsJwsAlgorithm;
|
|||
import static org.mitre.util.JsonUtils.getAsString;
|
||||
import static org.mitre.util.JsonUtils.getAsStringSet;
|
||||
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AppType;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType;
|
||||
import org.mitre.oauth2.model.RegisteredClient;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -45,13 +45,21 @@ import com.google.common.collect.Sets;
|
|||
@Entity
|
||||
@Table(name="approved_site")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "ApprovedSite.getAll", query = "select a from ApprovedSite a"),
|
||||
@NamedQuery(name = "ApprovedSite.getByUserId", query = "select a from ApprovedSite a where a.userId = :userId"),
|
||||
@NamedQuery(name = "ApprovedSite.getByClientId", query = "select a from ApprovedSite a where a.clientId = :clientId"),
|
||||
@NamedQuery(name = "ApprovedSite.getByClientIdAndUserId", query = "select a from ApprovedSite a where a.clientId = :clientId and a.userId = :userId")
|
||||
@NamedQuery(name = ApprovedSite.QUERY_ALL, query = "select a from ApprovedSite a"),
|
||||
@NamedQuery(name = ApprovedSite.QUERY_BY_USER_ID, query = "select a from ApprovedSite a where a.userId = :" + ApprovedSite.PARAM_USER_ID),
|
||||
@NamedQuery(name = ApprovedSite.QUERY_BY_CLIENT_ID, query = "select a from ApprovedSite a where a.clientId = :" + ApprovedSite.PARAM_CLIENT_ID),
|
||||
@NamedQuery(name = ApprovedSite.QUERY_BY_CLIENT_ID_AND_USER_ID, query = "select a from ApprovedSite a where a.clientId = :" + ApprovedSite.PARAM_CLIENT_ID + " and a.userId = :" + ApprovedSite.PARAM_USER_ID)
|
||||
})
|
||||
public class ApprovedSite {
|
||||
|
||||
public static final String QUERY_BY_CLIENT_ID_AND_USER_ID = "ApprovedSite.getByClientIdAndUserId";
|
||||
public static final String QUERY_BY_CLIENT_ID = "ApprovedSite.getByClientId";
|
||||
public static final String QUERY_BY_USER_ID = "ApprovedSite.getByUserId";
|
||||
public static final String QUERY_ALL = "ApprovedSite.getAll";
|
||||
|
||||
public static final String PARAM_CLIENT_ID = "clientId";
|
||||
public static final String PARAM_USER_ID = "userId";
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
|
|
|
@ -36,10 +36,12 @@ import javax.persistence.Table;
|
|||
@Entity
|
||||
@Table(name="blacklisted_site")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "BlacklistedSite.getAll", query = "select b from BlacklistedSite b")
|
||||
@NamedQuery(name = BlacklistedSite.QUERY_ALL, query = "select b from BlacklistedSite b")
|
||||
})
|
||||
public class BlacklistedSite {
|
||||
|
||||
public static final String QUERY_ALL = "BlacklistedSite.getAll";
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
|
|
|
@ -33,13 +33,14 @@ import com.google.gson.JsonObject;
|
|||
@Entity
|
||||
@Table(name="user_info")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="DefaultUserInfo.getByUsername", query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :username")
|
||||
@NamedQuery(name=DefaultUserInfo.QUERY_BY_USERNAME, query = "select u from DefaultUserInfo u WHERE u.preferredUsername = :" + DefaultUserInfo.PARAM_USERNAME)
|
||||
})
|
||||
public class DefaultUserInfo implements UserInfo {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String QUERY_BY_USERNAME = "DefaultUserInfo.getByUsername";
|
||||
|
||||
public static final String PARAM_USERNAME = "username";
|
||||
|
||||
private static final long serialVersionUID = 6078310513185681918L;
|
||||
private Long id;
|
||||
private String sub;
|
||||
|
|
|
@ -39,11 +39,17 @@ import javax.persistence.Table;
|
|||
@Entity
|
||||
@Table(name = "pairwise_identifier")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="PairwiseIdentifier.getAll", query = "select p from PairwiseIdentifier p"),
|
||||
@NamedQuery(name="PairwiseIdentifier.getBySectorIdentifier", query = "select p from PairwiseIdentifier p WHERE p.userSub = :sub AND p.sectorIdentifier = :sectorIdentifier")
|
||||
@NamedQuery(name=PairwiseIdentifier.QUERY_ALL, query = "select p from PairwiseIdentifier p"),
|
||||
@NamedQuery(name=PairwiseIdentifier.QUERY_BY_SECTOR_IDENTIFIER, query = "select p from PairwiseIdentifier p WHERE p.userSub = :" + PairwiseIdentifier.PARAM_SUB + " AND p.sectorIdentifier = :" + PairwiseIdentifier.PARAM_SECTOR_IDENTIFIER)
|
||||
})
|
||||
public class PairwiseIdentifier {
|
||||
|
||||
public static final String QUERY_BY_SECTOR_IDENTIFIER = "PairwiseIdentifier.getBySectorIdentifier";
|
||||
public static final String QUERY_ALL = "PairwiseIdentifier.getAll";
|
||||
|
||||
public static final String PARAM_SECTOR_IDENTIFIER = "sectorIdentifier";
|
||||
public static final String PARAM_SUB = "sub";
|
||||
|
||||
private Long id;
|
||||
private String identifier;
|
||||
private String userSub;
|
||||
|
@ -86,7 +92,7 @@ public class PairwiseIdentifier {
|
|||
* @return the userSub
|
||||
*/
|
||||
@Basic
|
||||
@Column(name = "sub")
|
||||
@Column(name = PairwiseIdentifier.PARAM_SUB)
|
||||
public String getUserSub() {
|
||||
return userSub;
|
||||
}
|
||||
|
|
|
@ -41,12 +41,19 @@ import javax.persistence.Table;
|
|||
@Entity
|
||||
@Table(name="whitelisted_site")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"),
|
||||
@NamedQuery(name = "WhitelistedSite.getByClientId", query = "select w from WhitelistedSite w where w.clientId = :clientId"),
|
||||
@NamedQuery(name = "WhitelistedSite.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId")
|
||||
@NamedQuery(name = WhitelistedSite.QUERY_ALL, query = "select w from WhitelistedSite w"),
|
||||
@NamedQuery(name = WhitelistedSite.QUERY_BY_CLIENT_ID, query = "select w from WhitelistedSite w where w.clientId = :" + WhitelistedSite.PARAM_CLIENT_ID),
|
||||
@NamedQuery(name = WhitelistedSite.QUERY_BY_CREATOR, query = "select w from WhitelistedSite w where w.creatorUserId = :" + WhitelistedSite.PARAM_USER_ID)
|
||||
})
|
||||
public class WhitelistedSite {
|
||||
|
||||
public static final String QUERY_BY_CREATOR = "WhitelistedSite.getByCreatoruserId";
|
||||
public static final String QUERY_BY_CLIENT_ID = "WhitelistedSite.getByClientId";
|
||||
public static final String QUERY_ALL = "WhitelistedSite.getAll";
|
||||
|
||||
public static final String PARAM_USER_ID = "userId";
|
||||
public static final String PARAM_CLIENT_ID = "clientId";
|
||||
|
||||
// unique id
|
||||
private Long id;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
|
@ -51,7 +52,7 @@ public class JWKSetView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
//BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys");
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.discovery.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
*
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
*/
|
||||
package org.mitre.jose;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
*
|
||||
* These tests make sure that the algorithm name processing
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.jose;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -39,6 +36,9 @@ import com.nimbusds.jose.jwk.KeyUse;
|
|||
import com.nimbusds.jose.jwk.RSAKey;
|
||||
import com.nimbusds.jose.util.Base64URL;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* @author tsitkov
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.jwt.encryption.service.impl;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.text.ParseException;
|
||||
|
@ -49,6 +44,12 @@ import com.nimbusds.jwt.EncryptedJWT;
|
|||
import com.nimbusds.jwt.JWTClaimsSet;
|
||||
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* @author wkim
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
package org.mitre.oauth2.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -29,6 +27,8 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
package org.mitre.oauth2.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.sql.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -29,6 +27,8 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
*/
|
||||
package org.mitre.openid.connect;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -34,6 +31,9 @@ import com.google.gson.JsonObject;
|
|||
import com.nimbusds.jose.EncryptionMethod;
|
||||
import com.nimbusds.jose.JWEAlgorithm;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.config;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>png</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>eot</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>svg</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>jwks</nonFilteredFileExtension>
|
||||
<nonFilteredFileExtension>json</nonFilteredFileExtension>
|
||||
</nonFilteredFileExtensions>
|
||||
<webResources>
|
||||
<resource>
|
||||
|
|
|
@ -52,7 +52,8 @@ CREATE TABLE IF NOT EXISTS client_authority (
|
|||
CREATE TABLE IF NOT EXISTS authorization_code (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
|
||||
code VARCHAR(256),
|
||||
authentication LONGVARBINARY
|
||||
auth_holder_id BIGINT,
|
||||
expiration TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS client_grant_type (
|
||||
|
|
|
@ -52,7 +52,8 @@ CREATE TABLE IF NOT EXISTS client_authority (
|
|||
CREATE TABLE IF NOT EXISTS authorization_code (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
code VARCHAR(256),
|
||||
authentication LONGBLOB
|
||||
auth_holder_id BIGINT,
|
||||
expiration TIMESTAMP NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS client_grant_type (
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
###############################################################################
|
||||
# Copyright 2015 The MITRE Corporation
|
||||
# and the MIT Kerberos and Internet Trust Consortium
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###############################################################################
|
||||
copyright=Powered by <a href="https://github.com/mitreid-connect/">MITREid Connect <span class="label">{0}</span></a> <span class="pull-right">© 2015 The MITRE Corporation and MIT KIT.</span>.
|
||||
|
||||
about.title=About
|
||||
about.body=\
|
||||
This OpenID Connect service is built from the MITREid Connect Open Source project, from \
|
||||
<a href="http://www.mitre.org/">The MITRE Corporation</a> and the <a href="http://kit.mit.edu/">MIT Kerberos and Internet Trust Consortium</a>.\
|
||||
</p>\
|
||||
<p>\
|
||||
More information about the project can be found at \
|
||||
<a href="http://github.com/mitreid-connect/">MITREid Connect on GitHub</a>. \
|
||||
There, you can submit bug reports, give feedback, or even contribute code patches for additional features you'd like to see.
|
||||
|
||||
statistics.title=Statistics
|
||||
statistics.number_users=Number of users: <span class="label label-info" id="userCount">{0}</span>
|
||||
statistics.number_clients=Authorized clients: <span class="label label-info" id="clientCount">{0}</span>
|
||||
statistics.number_approvals=Approved sites: <span class="label label-info" id="approvalCount">{0}</span>
|
||||
|
||||
home.welcome=Welcome!
|
||||
home.welcome.body=\
|
||||
OpenID Connect is an internet-scale federated identity protocol built on top of the OAuth2 authorization framework. \
|
||||
OpenID Connect lets you log into a remote site using your identity without exposing your credentials, like a username and password.</p>\
|
||||
<p><a class="btn btn-primary btn-large" href="http://openid.net/connect/">Learn more »</a>
|
||||
home.more=More
|
||||
home.about=About
|
||||
home.about.body=This OpenID Connect service is built from the MITREid Connect Open Source project, from \
|
||||
<a href="http://www.mitre.org/">The MITRE Corporation</a> and the <a href="http://kit.mit.edu/">MIT Kerberos and Internet Trust Consortium</a>.
|
||||
home.contact=Contact
|
||||
home.contact.body=\
|
||||
For more information or support, contact the administrators of this system.</p>\
|
||||
<p><a class="btn" href="mailto:idp@example.com?Subject=OpenID Connect">Email »</a>
|
||||
home.statistics=Current Statistics
|
||||
home.statistics.loading=Loading...
|
||||
home.statistics.number_users=Number of users: <span class="label label-info" id="userCount">{0}</span>
|
||||
home.statistics.number_clients=Authorized clients: <span class="label label-info" id="clientCount">{0}</span>
|
||||
home.statistics.number_approvals=Approved sites: <span class="label label-info" id="approvalCount">{0}</span>
|
||||
|
||||
contact.title=Contact
|
||||
contact.body=To report bugs with the MITREid Connect software itself, use the \
|
||||
<a href="https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/issues">GitHub issue tracker</a>. \
|
||||
For problems relating to this server, contact the server's administrator.
|
||||
|
||||
topbar.about=About
|
||||
topbar.contact=Contact
|
||||
topbar.statistics=Statistics
|
||||
topbar.home=Home
|
||||
topbar.login=Log in
|
||||
topbar.logout=Log out
|
||||
|
||||
sidebar.administrative=Administrative
|
||||
sidebar.administrative.manage_clients=Manage Clients
|
||||
sidebar.administrative.whitelisted_clients=Whitelisted Clients
|
||||
sidebar.administrative.blacklisted_clients=Blacklisted Clients
|
||||
sidebar.administrative.system_scopes=System Scopes
|
||||
sidebar.personal=Personal
|
||||
sidebar.personal.approved_sites=Manage Approved Sites
|
||||
sidebar.personal.active_tokens=Manage Active Tokens
|
||||
sidebar.personal.profile_information=View Profile Information
|
||||
sidebar.developer=Developer
|
||||
sidebar.developer.client_registration=Self-service client registration
|
||||
sidebar.developer.resource_registration=Self-service protected resource registration
|
||||
|
||||
manage.ok=OK
|
||||
manage.loading=Loading
|
||||
manage.title=Management Console
|
||||
|
||||
approve.title=Approve Access
|
||||
approve.error.not_granted=Access could not be granted.
|
||||
approve.required_for=Approval Required for
|
||||
approve.dynamically_registered=This client was dynamically registered
|
||||
approve.caution=Caution
|
||||
approve.caution.message.none=It has never been approved previously.
|
||||
approve.caution.message.singular=It has been approved <span class="label">{0}</span> time previously.
|
||||
approve.caution.message.plural=It has been approved <span class="label">{0}</span> times previously.
|
||||
approve.more_information=more information
|
||||
approve.home_page=Home page
|
||||
approve.policy=Policy
|
||||
approve.terms=Terms of Service
|
||||
approve.contacts=Administrative Contacts
|
||||
approve.warning=Warning
|
||||
approve.no_request_uri=This client does not have any redirect URIs registered and someone could be using a malicious URI here.
|
||||
approve.redirect_uri=You will be redirected to the following page if you click Approve: <code>{0}</code>
|
||||
approve.pairwise=This client uses a <b>pairwise</b> identifier, which makes it more difficult to correlate your identity between sites.
|
||||
approve.no_scopes=This client does not have any scopes registered and is therefore allowed to request <em>any</em> scopes available on the system. Proceed with caution.
|
||||
approve.access_to=Access to
|
||||
approve.remember=Remember this decision
|
||||
approve.remember.until_revoke=remember this decision until I revoke it
|
||||
approve.remember.one_hour=remember this decision for one hour
|
||||
approve.remember.next_time=prompt me again next time
|
||||
approve.do_authorize=Do you authorize
|
||||
approve.label.authorize=Authorize
|
||||
approve.label.deny=Deny
|
|
@ -1,112 +0,0 @@
|
|||
###############################################################################
|
||||
# Copyright 2015 The MITRE Corporation
|
||||
# and the MIT Kerberos and Internet Trust Consortium
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
###############################################################################
|
||||
copyright=Levererat av <a href="https://github.com/mitreid-connect/">MITREid Connect <span class="label">{0}</span></a> <span class="pull-right">© 2015 MITRE Corporation och MIT KIT.</span>.
|
||||
|
||||
about.title=Om tjänsten
|
||||
about.body=\
|
||||
Denna OpenID Connect-tjänst är baserad på öppen källkod ifrån projektet MITREid, skapat av \
|
||||
<a href="http://www.mitre.org/">MITRE Corporation</a> och <a href="http://kit.mit.edu/">MIT Kerberos and Internet Trust Consortium</a>.\
|
||||
</p>\
|
||||
<p>\
|
||||
Mer information om projektet kan finns i projektet \
|
||||
<a href="http://github.com/mitreid-connect/">MITREid Connect på GitHub</a>. \
|
||||
Där kan du skicka in felrapporter, komma med återkoppling, eller till och med bidra med kodtillägg för ytterligare funktioner du skulle vilja ha.
|
||||
|
||||
statistics.title=Statistik
|
||||
statistics.number_users=Antal användare: <span class="label label-info" id="userCount">{0}</span>
|
||||
statistics.number_clients=Auktoriserade klienter: <span class="label label-info" id="clientCount">{0}</span>
|
||||
statistics.number_approvals=Godkända webbplatser: <span class="label label-info" id="approvalCount">{0}</span>
|
||||
|
||||
# {2,choice,1#point|1<points}
|
||||
|
||||
home.title=Hem
|
||||
home.welcome=Välkommen!
|
||||
home.welcome.body=\
|
||||
OpenID Connect är ett internet-kapabelt federerat identitetsprotokoll byggt ovanpå autentiseringsramverket OAuth2. \
|
||||
OpenID Connect låter dig logga in på en webbplats med din identitet utan att avslöja dina inloggningshemligheter, som ett användarnamn och lösenord.</p>\
|
||||
<p><a class="btn btn-primary btn-large" href="http://openid.net/connect/">Lär dig mer »</a>
|
||||
home.more=Mer
|
||||
home.about=Om tjänsten
|
||||
home.about.body=\
|
||||
Denna OpenID Connect-tjänst är byggd från det öpnna källkodsprojektet MITREid, av \
|
||||
<a href="http://www.mitre.org/">MITRE Corporation</a> och <a href="http://kit.mit.edu/">MIT Kerberos and Internet Trust Consortium</a>.
|
||||
home.contact=Kontakt
|
||||
home.contact.body=\
|
||||
För mer information eller användarstöd, kontakta administratörerna av detta system.</p>\
|
||||
<p><a class="btn" href="mailto:idp@example.com?Subject=OpenID Connect">E-post »</a>
|
||||
home.statistics=Nuvarande statistik
|
||||
home.statistics.loading=Laddar...
|
||||
home.statistics.number_users=Antal användare: <span class="label label-info" id="userCount">{0}</span>
|
||||
home.statistics.number_clients=Auktoriserade klienter: <span class="label label-info" id="clientCount">{0}</span>
|
||||
home.statistics.number_approvals=Godkända webbplatser: <span class="label label-info" id="approvalCount">{0}</span>
|
||||
|
||||
contact.title=Kontakt
|
||||
contact.body=\
|
||||
För att rapportera fel i själva programvaran MITREid Connect, använd \
|
||||
<a href="https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/issues">GitHub issue tracker</a>. \
|
||||
För problem som är specifika för denna server, kontakta tjänstens administrator.
|
||||
|
||||
topbar.about=Om tjänsten
|
||||
topbar.contact=Kontakt
|
||||
topbar.statistics=Statistik
|
||||
topbar.home=Hem
|
||||
topbar.login=Logga in
|
||||
topbar.logout=Logga ut
|
||||
|
||||
sidebar.administrative=Administrativt
|
||||
sidebar.administrative.manage_clients=Hantera klienter
|
||||
sidebar.administrative.whitelisted_clients=Vitlistade klienter
|
||||
sidebar.administrative.blacklisted_clients=Svartlistade klienter
|
||||
sidebar.administrative.system_scopes=System-scope
|
||||
sidebar.personal=Personligt
|
||||
sidebar.personal.approved_sites=Hantera godkända platser
|
||||
sidebar.personal.active_tokens=Hantera aktiva biljetter
|
||||
sidebar.personal.profile_information=Visa profilinformation
|
||||
sidebar.developer=Utvecklare
|
||||
sidebar.developer.client_registration=Self-service klientregistering
|
||||
sidebar.developer.resource_registration=Self-service registrering av skyddad resurs
|
||||
|
||||
manage.ok=OK
|
||||
manage.loading=Laddar
|
||||
manage.title=Administrationsgränssnitt
|
||||
|
||||
approve.title=Medge åtkomst
|
||||
approve.error.not_granted=Åtkomst kunde inte medges.
|
||||
approve.required_for=Åtkomst måste medges för
|
||||
approve.dynamically_registered=Denna klient blev registrerad dynamiskt
|
||||
approve.caution=Försiktigt
|
||||
approve.caution.message.none=Den har aldrig tidigare blivit medgiven åtkomst.
|
||||
approve.caution.message.singular=Den har tidigare blivit medgiven åtkomst <span class="label">{0}</span> gång.
|
||||
approve.caution.message.plural=Den har tidigare blivit medgiven åtkomst <span class="label">{0}</span> gånger.
|
||||
approve.more_information=mer information
|
||||
approve.home_page=Hemsida
|
||||
approve.policy=Policy
|
||||
approve.terms=Användarvillkor
|
||||
approve.contacts=Administrativ kontakt
|
||||
approve.warning=Varning
|
||||
approve.no_request_uri=Denna klient har inte någon omdirigerings URI registrerad och någon kan använda en skadlig URI hit.
|
||||
approve.redirect_uri=Du kommer att omdirigeras till denna sida om du medger åtkomst: <code>{0}</code>
|
||||
approve.pairwise=Denna klient använder en <b>pairwise</b>-identifierare, vilket gör det svårare att koppla samman dina identititer mellan olika webbplatser.
|
||||
approve.no_scopes=Denna klient har inga "scopes" registrerade och kan därför begära <em>alla</em> scope som finns tillgängliga i systemet. Iakttag försiktighet.
|
||||
approve.access_to=Åtkomst till
|
||||
approve.remember=Kom ihåg detta val
|
||||
approve.remember.until_revoke=tills jag återkallar det
|
||||
approve.remember.one_hour=i en timme
|
||||
approve.remember.next_time=fråga igen nästa gång
|
||||
approve.do_authorize=Medger du åtkomst för
|
||||
approve.label.authorize=Medge åtkomst
|
||||
approve.label.deny=Avbryt
|
|
@ -22,10 +22,12 @@
|
|||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
|
||||
|
||||
|
@ -80,19 +82,19 @@
|
|||
<security:intercept-url pattern="/token" access="isAuthenticated()" />
|
||||
<security:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
|
||||
<!-- include this only if you need to authenticate clients via request parameters -->
|
||||
<security:custom-filter ref="clientAssertionTokenEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
<security:custom-filter ref="clientAssertionEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="clientCredentialsEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:access-denied-handler ref="oauthAccessDeniedHandler" />
|
||||
</security:http>
|
||||
|
||||
<!-- Allow open access to required endpoints -->
|
||||
<security:http pattern="/jwk**" use-expressions="true" entry-point-ref="http403EntryPoint" create-session="stateless">
|
||||
<security:intercept-url pattern="/jwk**" access="permitAll"/>
|
||||
<!-- Allow open access to discovery endpoints -->
|
||||
<security:http pattern="/#{T(org.mitre.openid.connect.web.JWKSetPublishingEndpoint).URL}**" use-expressions="true" entry-point-ref="http403EntryPoint" create-session="stateless">
|
||||
<security:intercept-url pattern="/#{T(org.mitre.openid.connect.web.JWKSetPublishingEndpoint).URL}**" access="permitAll"/>
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
</security:http>
|
||||
<security:http pattern="/.well-known/**" use-expressions="true" entry-point-ref="http403EntryPoint" create-session="stateless">
|
||||
<security:intercept-url pattern="/.well-known/**" access="permitAll"/>
|
||||
<security:http pattern="/#{T(org.mitre.discovery.web.DiscoveryEndpoint).WELL_KNOWN_URL}/**" use-expressions="true" entry-point-ref="http403EntryPoint" create-session="stateless">
|
||||
<security:intercept-url pattern="/#{T(org.mitre.discovery.web.DiscoveryEndpoint).WELL_KNOWN_URL}/**" access="permitAll"/>
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
</security:http>
|
||||
|
||||
|
@ -103,14 +105,14 @@
|
|||
</security:http>
|
||||
|
||||
<!-- OAuth-protect API and other endpoints -->
|
||||
<security:http pattern="/register/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:http pattern="/#{T(org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint).URL}/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:expression-handler ref="oauthWebExpressionHandler" />
|
||||
<security:intercept-url pattern="/register/**" access="permitAll"/>
|
||||
</security:http>
|
||||
|
||||
<security:http pattern="/resource/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:http pattern="/#{T(org.mitre.openid.connect.web.ProtectedResourceRegistrationEndpoint).URL}/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:expression-handler ref="oauthWebExpressionHandler" />
|
||||
|
@ -129,39 +131,39 @@
|
|||
<security:expression-handler ref="oauthWebExpressionHandler" />
|
||||
</security:http>
|
||||
|
||||
<security:http pattern="/userinfo**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:http pattern="/#{T(org.mitre.openid.connect.web.UserInfoEndpoint).URL}**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="stateless">
|
||||
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:expression-handler ref="oauthWebExpressionHandler" />
|
||||
</security:http>
|
||||
|
||||
<security:http pattern="/api/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="never">
|
||||
<security:http pattern="/#{T(org.mitre.openid.connect.web.RootController).API_URL}/**" use-expressions="true" entry-point-ref="oauthAuthenticationEntryPoint" create-session="never">
|
||||
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
|
||||
<security:expression-handler ref="oauthWebExpressionHandler" />
|
||||
</security:http>
|
||||
|
||||
<security:http pattern="/introspect**"
|
||||
<security:http pattern="/#{T(org.mitre.oauth2.web.IntrospectionEndpoint).URL}**"
|
||||
use-expressions="true"
|
||||
entry-point-ref="oauthAuthenticationEntryPoint"
|
||||
create-session="stateless"
|
||||
authentication-manager-ref="clientAuthenticationManager">
|
||||
<security:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
|
||||
<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
|
||||
<security:custom-filter ref="clientAssertionIntrospectionEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="clientAssertionEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:custom-filter ref="clientCredentialsIntrospectionEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
<security:custom-filter ref="clientCredentialsEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
</security:http>
|
||||
|
||||
<security:http pattern="/revoke**"
|
||||
<security:http pattern="/#{T(org.mitre.oauth2.web.RevocationEndpoint).URL}**"
|
||||
use-expressions="true"
|
||||
entry-point-ref="oauthAuthenticationEntryPoint"
|
||||
create-session="stateless"
|
||||
authentication-manager-ref="clientAuthenticationManager">
|
||||
<security:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
|
||||
<!-- <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> -->
|
||||
<security:custom-filter ref="clientAssertionRevocationEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="clientAssertionEndpointFilter" after="PRE_AUTH_FILTER" /> <!-- this one has to go first -->
|
||||
<security:custom-filter ref="corsFilter" after="SECURITY_CONTEXT_FILTER" />
|
||||
<security:custom-filter ref="clientCredentialsRevocationEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
<security:custom-filter ref="clientCredentialsEndpointFilter" after="BASIC_AUTH_FILTER" />
|
||||
</security:http>
|
||||
|
||||
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
|
||||
|
@ -174,36 +176,28 @@
|
|||
|
||||
<import resource="authz-config.xml" />
|
||||
|
||||
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/token"/>
|
||||
</bean>
|
||||
|
||||
<bean id="clientCredentialsIntrospectionEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/introspect"/>
|
||||
<bean id="oauth2ExceptionTranslator" class="org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator" />
|
||||
|
||||
<bean id="clientAuthMatcher" class="org.mitre.openid.connect.filter.MultiUrlRequestMatcher">
|
||||
<constructor-arg name="filterProcessesUrls">
|
||||
<set>
|
||||
<value>/introspect</value>
|
||||
<value>/revoke</value>
|
||||
<value>/token</value>
|
||||
</set>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="clientCredentialsRevocationEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||
<bean id="clientCredentialsEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/revoke"/>
|
||||
<property name="requiresAuthenticationRequestMatcher" ref="clientAuthMatcher" />
|
||||
</bean>
|
||||
|
||||
<bean id="clientAssertionTokenEndpointFilter" class="org.mitre.openid.connect.assertion.JWTBearerClientAssertionTokenEndpointFilter">
|
||||
<bean id="clientAssertionEndpointFilter" class="org.mitre.openid.connect.assertion.JWTBearerClientAssertionTokenEndpointFilter">
|
||||
<constructor-arg name="additionalMatcher" ref="clientAuthMatcher" />
|
||||
<property name="authenticationManager" ref="clientAssertionAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/token" />
|
||||
</bean>
|
||||
|
||||
<bean id="clientAssertionIntrospectionEndpointFilter" class="org.mitre.openid.connect.assertion.JWTBearerClientAssertionTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAssertionAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/introspect" />
|
||||
</bean>
|
||||
|
||||
<bean id="clientAssertionRevocationEndpointFilter" class="org.mitre.openid.connect.assertion.JWTBearerClientAssertionTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAssertionAuthenticationManager" />
|
||||
<property name="filterProcessesUrl" value="/revoke" />
|
||||
</bean>
|
||||
|
||||
<security:authentication-manager id="clientAuthenticationManager">
|
||||
<security:authentication-provider user-service-ref="clientUserDetailsService" />
|
||||
</security:authentication-manager>
|
||||
|
@ -215,18 +209,8 @@
|
|||
<bean id="clientAssertionAuthenticationProvider" class="org.mitre.openid.connect.assertion.JWTBearerAuthenticationProvider" />
|
||||
|
||||
<!-- Configure locale information -->
|
||||
<bean id="messageSource"
|
||||
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
|
||||
<property name="basenames">
|
||||
<list>
|
||||
<value>classpath:custom_messages</value>
|
||||
<value>classpath:messages</value>
|
||||
</list>
|
||||
</property>
|
||||
<property name="fallbackToSystemLocale" value="false" />
|
||||
<property name="cacheSeconds" value="180" />
|
||||
<property name="defaultEncoding" value="UTF-8" />
|
||||
<property name="useCodeAsDefaultMessage" value="true" />
|
||||
<bean id="messageSource" class="org.mitre.openid.connect.config.JsonMessageSource">
|
||||
<property name="baseDirectory" value="/resources/js/locale/" />
|
||||
</bean>
|
||||
|
||||
<!-- user services -->
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
<%@ taglib prefix="security"
|
||||
uri="http://www.springframework.org/security/tags"%>
|
||||
<security:authorize access="hasRole('ROLE_ADMIN')">
|
||||
<li class="nav-header"><spring:message code="sidebar.administrative"/></li>
|
||||
<li class="nav-header"><spring:message code="sidebar.administrative.title"/></li>
|
||||
<li><a href="manage/#admin/clients" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.administrative.manage_clients"/></a></li>
|
||||
<li><a href="manage/#admin/whitelists" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.administrative.whitelisted_clients"/></a></li>
|
||||
<li><a href="manage/#admin/blacklist" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.administrative.blacklisted_clients"/></a></li>
|
||||
<li><a href="manage/#admin/scope" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.administrative.system_scopes"/></a></li>
|
||||
<li class="divider"></li>
|
||||
</security:authorize>
|
||||
<li class="nav-header"><spring:message code="sidebar.personal"/></li>
|
||||
<li class="nav-header"><spring:message code="sidebar.personal.title"/></li>
|
||||
<li><a href="manage/#user/approved" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.personal.approved_sites"/></a></li>
|
||||
<li><a href="manage/#user/tokens" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.personal.active_tokens"/></a></li>
|
||||
<li><a href="manage/#user/profile" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.personal.profile_information"/></a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="nav-header"><spring:message code="sidebar.developer"/></li>
|
||||
<li class="nav-header"><spring:message code="sidebar.developer.title"/></li>
|
||||
<li><a href="manage/#dev/dynreg" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.developer.client_registration"/></a><li>
|
||||
<li><a href="manage/#dev/resource" data-toggle="collapse" data-target=".nav-collapse"><spring:message code="sidebar.developer.resource_registration"/></a><li>
|
|
@ -1,5 +1,5 @@
|
|||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
|
||||
<h2><spring:message code="home.about"/></h2>
|
||||
<h2><spring:message code="home.about.title"/></h2>
|
||||
|
||||
<p><spring:message code="home.about.body"/></p>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
|
||||
<h2><spring:message code="home.contact"/></h2>
|
||||
<h2><spring:message code="home.contact.title"/></h2>
|
||||
<p>
|
||||
<spring:message code="home.contact.body"/>
|
||||
</p>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
|
||||
<h2><spring:message code="home.statistics"/></h2>
|
||||
<h2><spring:message code="home.statistics.title"/></h2>
|
||||
|
||||
<p id="statsloader" class="muted"><spring:message code="home.statistics.loading"/></p>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="span2 visible-desktop"><img src="resources/images/openid_connect_large.png"/></div>
|
||||
|
||||
<div class="span10">
|
||||
<h1><spring:message code="home.welcome"/></h1>
|
||||
<h1><spring:message code="home.welcome.title"/></h1>
|
||||
<p><spring:message code="home.welcome.body"/></p>
|
||||
</div>
|
||||
</div>
|
|
@ -30,6 +30,7 @@
|
|||
<task:scheduled-tasks scheduler="taskScheduler">
|
||||
<task:scheduled ref="defaultOAuth2ProviderTokenService" method="clearExpiredTokens" fixed-delay="300000" initial-delay="600000"/>
|
||||
<task:scheduled ref="defaultApprovedSiteService" method="clearExpiredSites" fixed-delay="300000" initial-delay="600000"/>
|
||||
<task:scheduled ref="defaultOAuth2AuthorizationCodeService" method="clearExpiredAuthorizationCodes" fixed-delay="300000" initial-delay="600000"/>
|
||||
</task:scheduled-tasks>
|
||||
|
||||
</beans>
|
||||
|
|
|
@ -41,16 +41,15 @@
|
|||
<div class="row">
|
||||
<div class="span5 offset1 well-small" style="text-align: left">
|
||||
<c:if test="${ client.dynamicallyRegistered }">
|
||||
<fmt:formatDate type="both" value="${client.createdAt}" var="titleRegistrationTime"/>
|
||||
<fmt:formatDate type="date" value="${client.createdAt}" var="registrationTime"/>
|
||||
<c:choose>
|
||||
<c:when test="${ gras }">
|
||||
<!-- client is "generally recognized as safe, display a more muted block -->
|
||||
<div>
|
||||
<p class="alert alert-info">
|
||||
<i class="icon-globe"></i>
|
||||
|
||||
<spring:message code="approve.dynamically_registered"/>
|
||||
<span id="registrationTime" title='<c:out value="${titleRegistrationTime}"/>'> <c:out value="${registrationTime}"/></span>.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</c:when>
|
||||
|
@ -58,10 +57,13 @@
|
|||
<!-- client is dynamically registered -->
|
||||
<div class="alert alert-block <c:out value="${ count eq 0 ? 'alert-error' : 'alert-warn' }" />">
|
||||
<h4>
|
||||
<i class="icon-globe"></i> <spring:message code="approve.caution"/>:
|
||||
<i class="icon-globe"></i> <spring:message code="approve.caution.title"/>:
|
||||
</h4>
|
||||
<spring:message code="approve.dynamically_registered"/>
|
||||
<span id="registrationTime" title='<c:out value="${titleRegistrationTime}"/>'> <c:out value="${registrationTime}"/></span>.
|
||||
|
||||
<p>
|
||||
<spring:message code="approve.dynamically_registered" arguments="${ client.createdAt }"/>
|
||||
</p>
|
||||
<p>
|
||||
<c:choose>
|
||||
<c:when test="${count == 0}">
|
||||
<spring:message code="approve.caution.message.none" arguments="${count}"/>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<spring:message code="approve.caution.message.plural" arguments="${count}"/>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</p>
|
||||
</div>
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
|
@ -143,7 +146,7 @@
|
|||
<h4>
|
||||
<i class="icon-info-sign"></i> <spring:message code="approve.warning"/>:
|
||||
</h4>
|
||||
<spring:message code="approve.no_request_uri"/>
|
||||
<spring:message code="approve.no_redirect_uri"/>
|
||||
<spring:message code="approve.redirect_uri" arguments="${redirect_uri}"/>
|
||||
</div>
|
||||
</c:when>
|
||||
|
@ -225,7 +228,7 @@
|
|||
</fieldset>
|
||||
|
||||
<fieldset style="text-align: left" class="well">
|
||||
<legend style="margin-bottom: 0;"><spring:message code="approve.remember"/>:</legend>
|
||||
<legend style="margin-bottom: 0;"><spring:message code="approve.remember.title"/>:</legend>
|
||||
<label for="remember-forever" class="radio">
|
||||
<input type="radio" name="remember" id="remember-forever" value="until-revoked" ${ !consent ? 'checked="checked"' : '' }>
|
||||
<spring:message code="approve.remember.until_revoke"/>
|
||||
|
@ -294,6 +297,25 @@ $(document).ready(function() {
|
|||
$('#toggleMoreInformation i').attr('class', 'icon-chevron-down');
|
||||
}
|
||||
});
|
||||
|
||||
var creationDate = "<c:out value="${ client.createdAt }" />";
|
||||
var displayCreationDate = $.t('approve.dynamically-registered-unkown');
|
||||
var hoverCreationDate = "";
|
||||
if (creationDate != null && moment(creationDate).isValid()) {
|
||||
creationDate = moment(creationDate);
|
||||
if (moment().diff(creationDate, 'months') < 6) {
|
||||
displayCreationDate = creationDate.fromNow();
|
||||
} else {
|
||||
displayCreationDate = "on " + creationDate.format("LL");
|
||||
}
|
||||
hoverCreationDate = creationDate.format("LLL");
|
||||
}
|
||||
|
||||
$('#registrationTime').html(displayCreationDate);
|
||||
$('#registrationTime').attr('title', hoverCreationDate);
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
//-->
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
|
||||
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
|
||||
|
||||
<spring:message code="home.welcome" var="title"/>
|
||||
<spring:message code="home.title" var="title"/>
|
||||
<o:header title="${title}" />
|
||||
<o:topbar pageName="Home" />
|
||||
<div class="container-fluid main">
|
||||
|
|
|
@ -224,19 +224,19 @@ var ClientView = Backbone.View.extend({
|
|||
render:function (eventName) {
|
||||
|
||||
var creationDate = this.model.get('createdAt');
|
||||
var displayCreationDate = "at an unknown time";
|
||||
var displayCreationDate = $.t('client.client-table.unknown');
|
||||
var hoverCreationDate = "";
|
||||
if (creationDate == null || !moment(creationDate).isValid()) {
|
||||
displayCreationDate = "at an unknown time";
|
||||
displayCreationDate = $.t('client.client-table.unknown');
|
||||
hoverCreationDate = "";
|
||||
} else {
|
||||
creationDate = moment(creationDate);
|
||||
if (moment().diff(creationDate, 'months') < 6) {
|
||||
displayCreationDate = creationDate.fromNow();
|
||||
} else {
|
||||
displayCreationDate = "on " + creationDate.format("MMMM Do, YYYY");
|
||||
displayCreationDate = "on " + creationDate.format("LL");
|
||||
}
|
||||
hoverCreationDate = creationDate.format("MMMM Do, YYYY [at] h:mmA");
|
||||
hoverCreationDate = creationDate.format("LLL");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
"type": "Application Type",
|
||||
"type-native": "Native",
|
||||
"type-web": "Web",
|
||||
"unknown": "(Unknown)",
|
||||
"user-info-crypto-algorithm": "User Info Endpoint Encryption Algorithm",
|
||||
"user-info-crypto-method": "User Info Endpoint Encryption Method",
|
||||
"user-info-signing-algorithm": "User Info Endpoint Signing Algorithm"
|
||||
|
@ -185,7 +186,8 @@
|
|||
"no-redirect": "NO REDIRECT URI",
|
||||
"registered": "Registrered",
|
||||
"search": "Search...",
|
||||
"whitelist": "Whitelist"
|
||||
"whitelist": "Whitelist",
|
||||
"unknown": "at an unknown time"
|
||||
},
|
||||
"manage": "Manage Clients",
|
||||
"more-info": {
|
||||
|
@ -335,5 +337,116 @@
|
|||
"whitelist-table": {
|
||||
"no-sites": "There are no whitelisted sites. Use the <strong>whitelist</strong> button on the client management page to create one."
|
||||
}
|
||||
}
|
||||
},
|
||||
"copyright": "Powered by <a href=\"https://github.com/mitreid-connect/\">MITREid Connect <span class=\"label\">{0}</span></a> <span class=\"pull-right\">© 2015 The MITRE Corporation and MIT KIT.</span>.",
|
||||
"about": {
|
||||
"title": "About",
|
||||
"body": "\nThis OpenID Connect service is built from the MITREid Connect Open Source project, from \n<a href=\"http://www.mitre.org/\">The MITRE Corporation</a> and the <a href=\"http://kit.mit.edu/\">MIT Kerberos and Internet Trust Consortium</a>.\n</p>\n<p>\nMore information about the project can be found at \n<a href=\"http://github.com/mitreid-connect/\">MITREid Connect on GitHub</a>. \nThere, you can submit bug reports, give feedback, or even contribute code patches for additional features you'd like to see."
|
||||
},
|
||||
"statistics": {
|
||||
"title": "Statistics",
|
||||
"number_users": "Number of users: <span class=\"label label-info\" id=\"userCount\">{0}</span>",
|
||||
"number_clients": "Authorized clients: <span class=\"label label-info\" id=\"clientCount\">{0}</span>",
|
||||
"number_approvals": "Approved sites: <span class=\"label label-info\" id=\"approvalCount\">{0}</span>"
|
||||
},
|
||||
"home": {
|
||||
"title": "Home",
|
||||
"welcome": {
|
||||
"title": "Welcome!",
|
||||
"body": "\nOpenID Connect is an internet-scale federated identity protocol built on top of the OAuth2 authorization framework. \nOpenID Connect lets you log into a remote site using your identity without exposing your credentials, like a username and password.</p>\n<p><a class=\"btn btn-primary btn-large\" href=\"http://openid.net/connect/\">Learn more »</a>"
|
||||
},
|
||||
"more": "More",
|
||||
"about": {
|
||||
"title": "About",
|
||||
"body": "This OpenID Connect service is built from the MITREid Connect Open Source project, from \n<a href=\"http://www.mitre.org/\">The MITRE Corporation</a> and the <a href=\"http://kit.mit.edu/\">MIT Kerberos and Internet Trust Consortium</a>."
|
||||
},
|
||||
"contact": {
|
||||
"title": "Contact",
|
||||
"body": "\nFor more information or support, contact the administrators of this system.</p>\n<p><a class=\"btn\" href=\"mailto:idp@example.com?Subject=OpenID Connect\">Email »</a>"
|
||||
},
|
||||
"statistics": {
|
||||
"title": "Current Statistics",
|
||||
"loading": "Loading...",
|
||||
"number_users": "Number of users: <span class=\"label label-info\" id=\"userCount\">{0}</span>",
|
||||
"number_clients": "Authorized clients: <span class=\"label label-info\" id=\"clientCount\">{0}</span>",
|
||||
"number_approvals": "Approved sites: <span class=\"label label-info\" id=\"approvalCount\">{0}</span>"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"title": "Contact",
|
||||
"body": "To report bugs with the MITREid Connect software itself, use the \n<a href=\"https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/issues\">GitHub issue tracker</a>. \nFor problems relating to this server, contact the server's administrator."
|
||||
},
|
||||
"topbar": {
|
||||
"about": "About",
|
||||
"contact": "Contact",
|
||||
"statistics": "Statistics",
|
||||
"home": "Home",
|
||||
"login": "Log in",
|
||||
"logout": "Log out"
|
||||
},
|
||||
"sidebar": {
|
||||
"administrative": {
|
||||
"title": "Administrative",
|
||||
"manage_clients": "Manage Clients",
|
||||
"whitelisted_clients": "Whitelisted Clients",
|
||||
"blacklisted_clients": "Blacklisted Clients",
|
||||
"system_scopes": "System Scopes"
|
||||
},
|
||||
"personal": {
|
||||
"title": "Personal",
|
||||
"approved_sites": "Manage Approved Sites",
|
||||
"active_tokens": "Manage Active Tokens",
|
||||
"profile_information": "View Profile Information"
|
||||
},
|
||||
"developer": {
|
||||
"title": "Developer",
|
||||
"client_registration": "Self-service client registration",
|
||||
"resource_registration": "Self-service protected resource registration"
|
||||
}
|
||||
},
|
||||
"manage": {
|
||||
"ok": "OK",
|
||||
"loading": "Loading",
|
||||
"title": "Management Console"
|
||||
},
|
||||
"approve": {
|
||||
"dynamically-registered-unknown": "at an unknown time",
|
||||
"title": "Approve Access",
|
||||
"error": {
|
||||
"not_granted": "Access could not be granted."
|
||||
},
|
||||
"required_for": "Approval Required for",
|
||||
"dynamically_registered": "This client was dynamically registered <span class=\"label label-info\" id=\"registrationTime\">{0}</span>.",
|
||||
"caution": {
|
||||
"title": "Caution",
|
||||
"message": {
|
||||
"none": "It has <span class=\"label label-important\">never</span> been approved previously.",
|
||||
"singular": "It has been approved <span class=\"label label-warning\">{0}</span> time previously.",
|
||||
"plural": "It has been approved <span class=\"label\">{0}</span> times previously."
|
||||
}
|
||||
},
|
||||
"more_information": "more information",
|
||||
"home_page": "Home page",
|
||||
"policy": "Policy",
|
||||
"terms": "Terms of Service",
|
||||
"contacts": "Administrative Contacts",
|
||||
"warning": "Warning",
|
||||
"no_redirect_uri": "This client does not have any redirect URIs registered and someone could be using a malicious URI here.",
|
||||
"redirect_uri": "You will be redirected to the following page if you click Approve: <code>{0}</code>",
|
||||
"pairwise": "This client uses a <b>pairwise</b> identifier, which makes it more difficult to correlate your identity between sites.",
|
||||
"no_scopes": "This client does not have any scopes registered and is therefore allowed to request <em>any</em> scopes available on the system. Proceed with caution.",
|
||||
"access_to": "Access to",
|
||||
"remember": {
|
||||
"title": "Remember this decision",
|
||||
"until_revoke": "remember this decision until I revoke it",
|
||||
"one_hour": "remember this decision for one hour",
|
||||
"next_time": "prompt me again next time"
|
||||
},
|
||||
"do_authorize": "Do you authorize",
|
||||
"label": {
|
||||
"authorize": "Authorize",
|
||||
"deny": "Deny"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -322,5 +322,115 @@
|
|||
"whitelist-table": {
|
||||
"no-sites": "Det finns inga vitlistade webbplatser. Använd knappen <strong>vitlista</strong> på klientadminstrationssidan för att skapa en."
|
||||
}
|
||||
}
|
||||
},
|
||||
"copyright": "Levererat av <a href=\"https://github.com/mitreid-connect/\">MITREid Connect <span class=\"label\">{0}</span></a> <span class=\"pull-right\">© 2015 MITRE Corporation och MIT KIT.</span>.",
|
||||
"about": {
|
||||
"title": "Om tjänsten",
|
||||
"body": "\nDenna OpenID Connect-tjänst är baserad på öppen källkod ifrån projektet MITREid, skapat av \n<a href=\"http://www.mitre.org/\">MITRE Corporation</a> och <a href=\"http://kit.mit.edu/\">MIT Kerberos and Internet Trust Consortium</a>.\n</p>\n<p>\nMer information om projektet kan finns i projektet \n<a href=\"http://github.com/mitreid-connect/\">MITREid Connect på GitHub</a>. \nDär kan du skicka in felrapporter, komma med återkoppling, eller till och med bidra med kodtillägg för ytterligare funktioner du skulle vilja ha."
|
||||
},
|
||||
"statistics": {
|
||||
"title": "Statistik",
|
||||
"number_users": "Antal användare: <span class=\"label label-info\" id=\"userCount\">{0}</span>",
|
||||
"number_clients": "Auktoriserade klienter: <span class=\"label label-info\" id=\"clientCount\">{0}</span>",
|
||||
"number_approvals": "Godkända webbplatser: <span class=\"label label-info\" id=\"approvalCount\">{0}</span>"
|
||||
},
|
||||
"home": {
|
||||
"title": "Hem",
|
||||
"welcome": {
|
||||
"title": "Välkommen!",
|
||||
"body": "\nOpenID Connect är ett internet-kapabelt federerat identitetsprotokoll byggt ovanpå autentiseringsramverket OAuth2. \nOpenID Connect låter dig logga in på en webbplats med din identitet utan att avslöja dina inloggningshemligheter, som ett användarnamn och lösenord.</p>\n<p><a class=\"btn btn-primary btn-large\" href=\"http://openid.net/connect/\">Lär dig mer »</a>"
|
||||
},
|
||||
"more": "Mer",
|
||||
"about": {
|
||||
"title": "Om tjänsten",
|
||||
"body": "\nDenna OpenID Connect-tjänst är byggd från det öpnna källkodsprojektet MITREid, av \n<a href=\"http://www.mitre.org/\">MITRE Corporation</a> och <a href=\"http://kit.mit.edu/\">MIT Kerberos and Internet Trust Consortium</a>."
|
||||
},
|
||||
"contact": {
|
||||
"title": "Kontakt",
|
||||
"body": "\nFör mer information eller användarstöd, kontakta administratörerna av detta system.</p>\n<p><a class=\"btn\" href=\"mailto:idp@example.com?Subject=OpenID Connect\">E-post »</a>"
|
||||
},
|
||||
"statistics": {
|
||||
"title": "Nuvarande statistik",
|
||||
"loading": "Laddar...",
|
||||
"number_users": "Antal användare: <span class=\"label label-info\" id=\"userCount\">{0}</span>",
|
||||
"number_clients": "Auktoriserade klienter: <span class=\"label label-info\" id=\"clientCount\">{0}</span>",
|
||||
"number_approvals": "Godkända webbplatser: <span class=\"label label-info\" id=\"approvalCount\">{0}</span>"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"title": "Kontakt",
|
||||
"body": "\nFör att rapportera fel i själva programvaran MITREid Connect, använd \n<a href=\"https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server/issues\">GitHub issue tracker</a>. \nFör problem som är specifika för denna server, kontakta tjänstens administrator."
|
||||
},
|
||||
"topbar": {
|
||||
"about": "Om tjänsten",
|
||||
"contact": "Kontakt",
|
||||
"statistics": "Statistik",
|
||||
"home": "Hem",
|
||||
"login": "Logga in",
|
||||
"logout": "Logga ut"
|
||||
},
|
||||
"sidebar": {
|
||||
"administrative": {
|
||||
"title": "Administrativt",
|
||||
"manage_clients": "Hantera klienter",
|
||||
"whitelisted_clients": "Vitlistade klienter",
|
||||
"blacklisted_clients": "Svartlistade klienter",
|
||||
"system_scopes": "System-scope"
|
||||
},
|
||||
"personal": {
|
||||
"title": "Personligt",
|
||||
"approved_sites": "Hantera godkända platser",
|
||||
"active_tokens": "Hantera aktiva biljetter",
|
||||
"profile_information": "Visa profilinformation"
|
||||
},
|
||||
"developer": {
|
||||
"title": "Utvecklare",
|
||||
"client_registration": "Self-service klientregistering",
|
||||
"resource_registration": "Self-service registrering av skyddad resurs"
|
||||
}
|
||||
},
|
||||
"manage": {
|
||||
"ok": "OK",
|
||||
"loading": "Laddar",
|
||||
"title": "Administrationsgränssnitt"
|
||||
},
|
||||
"approve": {
|
||||
"dynamically-registered-unknown": "(Okänt)",
|
||||
"title": "Medge åtkomst",
|
||||
"error": {
|
||||
"not_granted": "Åtkomst kunde inte medges."
|
||||
},
|
||||
"required_for": "Åtkomst måste medges för",
|
||||
"dynamically_registered": "Denna klient blev registrerad dynamiskt <span class=\"label label-info\" id=\"registrationTime\">{0}</span>.",
|
||||
"caution": {
|
||||
"title": "Försiktigt",
|
||||
"message": {
|
||||
"none": "Den har <span class=\"label label-important\">aldrig</span> tidigare blivit medgiven åtkomst.",
|
||||
"singular": "Den har tidigare blivit medgiven åtkomst <span class=\"label label-warning\">{0}</span> gång.",
|
||||
"plural": "Den har tidigare blivit medgiven åtkomst <span class=\"label\">{0}</span> gånger."
|
||||
}
|
||||
},
|
||||
"more_information": "mer information",
|
||||
"home_page": "Hemsida",
|
||||
"policy": "Policy",
|
||||
"terms": "Användarvillkor",
|
||||
"contacts": "Administrativ kontakt",
|
||||
"warning": "Varning",
|
||||
"no_redirect_uri": "Denna klient har inte någon omdirigerings URI registrerad och någon kan använda en skadlig URI hit.",
|
||||
"redirect_uri": "Du kommer att omdirigeras till denna sida om du medger åtkomst: <code>{0}</code>",
|
||||
"pairwise": "Denna klient använder en <b>pairwise</b>-identifierare, vilket gör det svårare att koppla samman dina identititer mellan olika webbplatser.",
|
||||
"no_scopes": "Denna klient har inga \"scopes\" registrerade och kan därför begära <em>alla</em> scope som finns tillgängliga i systemet. Iakttag försiktighet.",
|
||||
"access_to": "Åtkomst till",
|
||||
"remember": {
|
||||
"title": "Kom ihåg detta val",
|
||||
"until_revoke": "tills jag återkallar det",
|
||||
"one_hour": "i en timme",
|
||||
"next_time": "fråga igen nästa gång"
|
||||
},
|
||||
"do_authorize": "Medger du åtkomst för",
|
||||
"label": {
|
||||
"authorize": "Medge åtkomst",
|
||||
"deny": "Avbryt"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -195,7 +195,11 @@
|
|||
<div class="control-group" id="createdAt">
|
||||
<label class="control-label" data-i18n="client.client-form.registered">Registered at</label>
|
||||
<div class="controls">
|
||||
<%-createdAt%>
|
||||
<% if (createdAt) { %>
|
||||
<%-createdAt%>
|
||||
<% } else { %>
|
||||
<span data-i18n="client.client-form.unknown">Unknown</span>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -410,7 +414,7 @@
|
|||
<label class="control-label" data-i18n="client.client-form.authentication-method">Token Endpoint Authentication Method</label>
|
||||
<div class="controls">
|
||||
<div>
|
||||
<input type="radio" id="tokenEndpointAuthMethodBasic" name="tokenEndpointAuthMethod" value="SECRET_BASIC" <%-(tokenEndpointAuthMethod == 'SECRET_BASIC' ? 'checked' : '')%>>
|
||||
<input type="radio" id="tokenEndpointAuthMethodBasic" name="tokenEndpointAuthMethod" value="SECRET_BASIC" <%-((tokenEndpointAuthMethod == 'SECRET_BASIC') || (!tokenEndpointAuthMethod) ? 'checked' : '')%>>
|
||||
<label for="tokenEndpointAuthMethodBasic" class="radio" data-i18n="client.client-form.secret-http">Client Secret over HTTP Basic</label>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -81,7 +82,7 @@ public class WebfingerView extends AbstractView {
|
|||
response.setContentType("application/jrd+json");
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.mitre.discovery.util.WebfingerURLNormalizer;
|
|||
import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService;
|
||||
import org.mitre.jwt.signer.service.JWTSigningAndValidationService;
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.oauth2.web.IntrospectionEndpoint;
|
||||
import org.mitre.oauth2.web.RevocationEndpoint;
|
||||
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.service.UserInfoService;
|
||||
|
@ -32,10 +34,14 @@ import org.mitre.openid.connect.view.HttpCodeView;
|
|||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.uma.web.PermissionRegistrationEndpoint;
|
||||
import org.mitre.uma.web.ResourceSetRegistrationEndpoint;
|
||||
import org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint;
|
||||
import org.mitre.openid.connect.web.JWKSetPublishingEndpoint;
|
||||
import org.mitre.openid.connect.web.UserInfoEndpoint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -61,6 +67,10 @@ import com.nimbusds.jose.JWSAlgorithm;
|
|||
@Controller
|
||||
public class DiscoveryEndpoint {
|
||||
|
||||
public static final String WELL_KNOWN_URL = ".well-known";
|
||||
public static final String OPENID_CONFIGURATION_URL = WELL_KNOWN_URL + "/openid-configuration";
|
||||
public static final String WEBFINGER_URL = WELL_KNOWN_URL + "/webfinger";
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -94,8 +104,8 @@ public class DiscoveryEndpoint {
|
|||
}
|
||||
};
|
||||
|
||||
@RequestMapping(value={"/.well-known/webfinger"},
|
||||
params={"resource", "rel=http://openid.net/specs/connect/1.0/issuer"}, produces = "application/json")
|
||||
@RequestMapping(value={"/" + WEBFINGER_URL},
|
||||
params={"resource", "rel=http://openid.net/specs/connect/1.0/issuer"}, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String webfinger(@RequestParam("resource") String resource, Model model) {
|
||||
|
||||
if (!resource.equals(config.getIssuer())) {
|
||||
|
@ -111,7 +121,7 @@ public class DiscoveryEndpoint {
|
|||
|
||||
if (user == null) {
|
||||
logger.info("User not found: " + resource);
|
||||
model.addAttribute("code", HttpStatus.NOT_FOUND);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -119,14 +129,14 @@ public class DiscoveryEndpoint {
|
|||
if (!Strings.nullToEmpty(issuerComponents.getHost())
|
||||
.equals(Strings.nullToEmpty(resourceUri.getHost()))) {
|
||||
logger.info("Host mismatch, expected " + issuerComponents.getHost() + " got " + resourceUri.getHost());
|
||||
model.addAttribute("code", HttpStatus.NOT_FOUND);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
logger.info("Unknown URI format: " + resource);
|
||||
model.addAttribute("code", HttpStatus.NOT_FOUND);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +148,7 @@ public class DiscoveryEndpoint {
|
|||
return "webfingerView";
|
||||
}
|
||||
|
||||
@RequestMapping("/.well-known/openid-configuration")
|
||||
@RequestMapping("/" + OPENID_CONFIGURATION_URL)
|
||||
public String providerConfiguration(Model model) {
|
||||
|
||||
/*
|
||||
|
@ -277,11 +287,11 @@ public class DiscoveryEndpoint {
|
|||
m.put("issuer", config.getIssuer());
|
||||
m.put("authorization_endpoint", baseUrl + "authorize");
|
||||
m.put("token_endpoint", baseUrl + "token");
|
||||
m.put("userinfo_endpoint", baseUrl + "userinfo");
|
||||
m.put("userinfo_endpoint", baseUrl + UserInfoEndpoint.URL);
|
||||
//check_session_iframe
|
||||
//end_session_endpoint
|
||||
m.put("jwks_uri", baseUrl + "jwk");
|
||||
m.put("registration_endpoint", baseUrl + "register");
|
||||
m.put("jwks_uri", baseUrl + JWKSetPublishingEndpoint.URL);
|
||||
m.put("registration_endpoint", baseUrl + DynamicClientRegistrationEndpoint.URL);
|
||||
m.put("scopes_supported", scopeService.toStrings(scopeService.getUnrestricted())); // these are the scopes that you can dynamically register for, which is what matters for discovery
|
||||
m.put("response_types_supported", Lists.newArrayList("code", "token")); // we don't support these yet: , "id_token", "id_token token"));
|
||||
m.put("grant_types_supported", grantTypes);
|
||||
|
@ -332,10 +342,10 @@ public class DiscoveryEndpoint {
|
|||
m.put("op_policy_uri", baseUrl + "about");
|
||||
m.put("op_tos_uri", baseUrl + "about");
|
||||
|
||||
m.put("introspection_endpoint", baseUrl + "introspect"); // token introspection endpoint for verifying tokens
|
||||
m.put("revocation_endpoint", baseUrl + "revoke"); // token revocation endpoint
|
||||
m.put("introspection_endpoint", baseUrl + IntrospectionEndpoint.URL); // token introspection endpoint for verifying tokens
|
||||
m.put("revocation_endpoint", baseUrl + RevocationEndpoint.URL); // token revocation endpoint
|
||||
|
||||
model.addAttribute("entity", m);
|
||||
model.addAttribute(JsonEntityView.ENTITY, m);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import javax.persistence.TypedQuery;
|
|||
import org.mitre.oauth2.model.AuthenticationHolderEntity;
|
||||
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -40,7 +39,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe
|
|||
|
||||
@Override
|
||||
public List<AuthenticationHolderEntity> getAll() {
|
||||
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery("AuthenticationHolderEntity.getAll", AuthenticationHolderEntity.class);
|
||||
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery(AuthenticationHolderEntity.QUERY_ALL, AuthenticationHolderEntity.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
@ -69,7 +68,7 @@ public class JpaAuthenticationHolderRepository implements AuthenticationHolderRe
|
|||
@Override
|
||||
@Transactional
|
||||
public List<AuthenticationHolderEntity> getOrphanedAuthenticationHolders() {
|
||||
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery("AuthenticationHolderEntity.getUnusedAuthenticationHolders", AuthenticationHolderEntity.class);
|
||||
TypedQuery<AuthenticationHolderEntity> query = manager.createNamedQuery(AuthenticationHolderEntity.QUERY_GET_UNUSED, AuthenticationHolderEntity.class);
|
||||
query.setMaxResults(MAXEXPIREDRESULTS);
|
||||
List<AuthenticationHolderEntity> unusedAuthenticationHolders = query.getResultList();
|
||||
return unusedAuthenticationHolders;
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
*/
|
||||
package org.mitre.oauth2.repository.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
@ -26,8 +29,6 @@ import javax.persistence.TypedQuery;
|
|||
import org.mitre.oauth2.model.AuthorizationCodeEntity;
|
||||
import org.mitre.oauth2.repository.AuthorizationCodeRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -56,27 +57,39 @@ public class JpaAuthorizationCodeRepository implements AuthorizationCodeReposito
|
|||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#consume(java.lang.String)
|
||||
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#getByCode(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public OAuth2Authentication consume(String code) throws InvalidGrantException {
|
||||
|
||||
TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery("AuthorizationCodeEntity.getByValue", AuthorizationCodeEntity.class);
|
||||
public AuthorizationCodeEntity getByCode(String code) {
|
||||
TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery(AuthorizationCodeEntity.QUERY_BY_VALUE, AuthorizationCodeEntity.class);
|
||||
query.setParameter("code", code);
|
||||
|
||||
AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList());
|
||||
|
||||
if (result == null) {
|
||||
throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code);
|
||||
}
|
||||
|
||||
OAuth2Authentication authRequest = result.getAuthentication();
|
||||
|
||||
manager.remove(result);
|
||||
|
||||
return authRequest;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#remove(org.mitre.oauth2.model.AuthorizationCodeEntity)
|
||||
*/
|
||||
@Override
|
||||
public void remove(AuthorizationCodeEntity authorizationCodeEntity) {
|
||||
AuthorizationCodeEntity found = manager.find(AuthorizationCodeEntity.class, authorizationCodeEntity.getId());
|
||||
if (found != null) {
|
||||
manager.remove(found);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.mitre.oauth2.repository.AuthorizationCodeRepository#getExpiredCodes()
|
||||
*/
|
||||
@Override
|
||||
public Collection<AuthorizationCodeEntity> getExpiredCodes() {
|
||||
TypedQuery<AuthorizationCodeEntity> query = manager.createNamedQuery(AuthorizationCodeEntity.QUERY_EXPIRATION_BY_DATE, AuthorizationCodeEntity.class);
|
||||
query.setParameter(AuthorizationCodeEntity.PARAM_DATE, new Date()); // this gets anything that's already expired
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -57,8 +57,8 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
|
|||
*/
|
||||
@Override
|
||||
public ClientDetailsEntity getClientByClientId(String clientId) {
|
||||
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery("ClientDetailsEntity.getByClientId", ClientDetailsEntity.class);
|
||||
query.setParameter("clientId", clientId);
|
||||
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery(ClientDetailsEntity.QUERY_BY_CLIENT_ID, ClientDetailsEntity.class);
|
||||
query.setParameter(ClientDetailsEntity.PARAM_CLIENT_ID, clientId);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class JpaOAuth2ClientRepository implements OAuth2ClientRepository {
|
|||
|
||||
@Override
|
||||
public Collection<ClientDetailsEntity> getAllClients() {
|
||||
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery("ClientDetailsEntity.findAll", ClientDetailsEntity.class);
|
||||
TypedQuery<ClientDetailsEntity> query = manager.createNamedQuery(ClientDetailsEntity.QUERY_ALL, ClientDetailsEntity.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,21 +44,21 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
|
||||
@Override
|
||||
public Set<OAuth2AccessTokenEntity> getAllAccessTokens() {
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getAll", OAuth2AccessTokenEntity.class);
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_ALL, OAuth2AccessTokenEntity.class);
|
||||
return new LinkedHashSet<OAuth2AccessTokenEntity>(query.getResultList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<OAuth2RefreshTokenEntity> getAllRefreshTokens() {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery("OAuth2RefreshTokenEntity.getAll", OAuth2RefreshTokenEntity.class);
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_ALL, OAuth2RefreshTokenEntity.class);
|
||||
return new LinkedHashSet<OAuth2RefreshTokenEntity>(query.getResultList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByTokenValue", OAuth2AccessTokenEntity.class);
|
||||
query.setParameter("tokenValue", accessTokenValue);
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_TOKEN_VALUE, OAuth2AccessTokenEntity.class);
|
||||
query.setParameter(OAuth2AccessTokenEntity.PARAM_TOKEN_VALUE, accessTokenValue);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,8 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getByRefreshToken", OAuth2AccessTokenEntity.class);
|
||||
query.setParameter("refreshToken", refreshToken);
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_REFRESH_TOKEN, OAuth2AccessTokenEntity.class);
|
||||
query.setParameter(OAuth2AccessTokenEntity.PARAM_REFERSH_TOKEN, refreshToken);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = query.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
|
@ -97,8 +97,8 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
|
||||
@Override
|
||||
public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue) {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByTokenValue", OAuth2RefreshTokenEntity.class);
|
||||
query.setParameter("tokenValue", refreshTokenValue);
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_BY_TOKEN_VALUE, OAuth2RefreshTokenEntity.class);
|
||||
query.setParameter(OAuth2RefreshTokenEntity.PARAM_TOKEN_VALUE, refreshTokenValue);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
@ -127,14 +127,14 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public void clearTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("client", client);
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_CLIENT, OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter(OAuth2AccessTokenEntity.PARAM_CLIENT, client);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
for (OAuth2AccessTokenEntity accessToken : accessTokens) {
|
||||
removeAccessToken(accessToken);
|
||||
}
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter("client", client);
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter(OAuth2RefreshTokenEntity.PARAM_CLIENT, client);
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) {
|
||||
removeRefreshToken(refreshToken);
|
||||
|
@ -146,8 +146,8 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
*/
|
||||
@Override
|
||||
public List<OAuth2AccessTokenEntity> getAccessTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByClient", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("client", client);
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_CLIENT, OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter(OAuth2AccessTokenEntity.PARAM_CLIENT, client);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return accessTokens;
|
||||
}
|
||||
|
@ -157,16 +157,16 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
*/
|
||||
@Override
|
||||
public List<OAuth2RefreshTokenEntity> getRefreshTokensForClient(ClientDetailsEntity client) {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery("OAuth2RefreshTokenEntity.getByClient", OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter("client", client);
|
||||
TypedQuery<OAuth2RefreshTokenEntity> queryR = manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, OAuth2RefreshTokenEntity.class);
|
||||
queryR.setParameter(OAuth2RefreshTokenEntity.PARAM_CLIENT, client);
|
||||
List<OAuth2RefreshTokenEntity> refreshTokens = queryR.getResultList();
|
||||
return refreshTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getByAuthentication(OAuth2Authentication auth) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByAuthentication", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("authentication", auth);
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_AUTHENTICATION, OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter(OAuth2AccessTokenEntity.PARAM_AUTHENTICATION, auth);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
|
@ -176,24 +176,24 @@ public class JpaOAuth2TokenRepository implements OAuth2TokenRepository {
|
|||
*/
|
||||
@Override
|
||||
public OAuth2AccessTokenEntity getAccessTokenForIdToken(OAuth2AccessTokenEntity idToken) {
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery("OAuth2AccessTokenEntity.getByIdToken", OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter("idToken", idToken);
|
||||
TypedQuery<OAuth2AccessTokenEntity> queryA = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_ID_TOKEN, OAuth2AccessTokenEntity.class);
|
||||
queryA.setParameter(OAuth2AccessTokenEntity.PARAM_ID_TOKEN, idToken);
|
||||
List<OAuth2AccessTokenEntity> accessTokens = queryA.getResultList();
|
||||
return JpaUtil.getSingleResult(accessTokens);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<OAuth2AccessTokenEntity> getAllExpiredAccessTokens() {
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery("OAuth2AccessTokenEntity.getAllExpiredByDate", OAuth2AccessTokenEntity.class);
|
||||
query.setParameter("date", new Date());
|
||||
TypedQuery<OAuth2AccessTokenEntity> query = manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_EXPIRED_BY_DATE, OAuth2AccessTokenEntity.class);
|
||||
query.setParameter(OAuth2AccessTokenEntity.PARAM_DATE, new Date());
|
||||
query.setMaxResults(MAXEXPIREDRESULTS);
|
||||
return new LinkedHashSet<OAuth2AccessTokenEntity>(query.getResultList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<OAuth2RefreshTokenEntity> getAllExpiredRefreshTokens() {
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery("OAuth2RefreshTokenEntity.getAllExpiredByDate", OAuth2RefreshTokenEntity.class);
|
||||
query.setParameter("date", new Date());
|
||||
TypedQuery<OAuth2RefreshTokenEntity> query = manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_EXPIRED_BY_DATE, OAuth2RefreshTokenEntity.class);
|
||||
query.setParameter(OAuth2RefreshTokenEntity.PARAM_DATE, new Date());
|
||||
query.setMaxResults(MAXEXPIREDRESULTS);
|
||||
return new LinkedHashSet<OAuth2RefreshTokenEntity>(query.getResultList());
|
||||
}
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
*/
|
||||
package org.mitre.oauth2.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -34,6 +31,9 @@ import org.mitre.oauth2.repository.SystemScopeRepository;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -50,7 +50,7 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Set<SystemScope> getAll() {
|
||||
TypedQuery<SystemScope> query = em.createNamedQuery("SystemScope.findAll", SystemScope.class);
|
||||
TypedQuery<SystemScope> query = em.createNamedQuery(SystemScope.QUERY_ALL, SystemScope.class);
|
||||
|
||||
return new LinkedHashSet<SystemScope>(query.getResultList());
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ public class JpaSystemScopeRepository implements SystemScopeRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public SystemScope getByValue(String value) {
|
||||
TypedQuery<SystemScope> query = em.createNamedQuery("SystemScope.getByValue", SystemScope.class);
|
||||
query.setParameter("value", value);
|
||||
TypedQuery<SystemScope> query = em.createNamedQuery(SystemScope.QUERY_BY_VALUE, SystemScope.class);
|
||||
query.setParameter(SystemScope.PARAM_VALUE, value);
|
||||
return getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,10 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.oauth2.service.impl;
|
||||
|
||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
||||
import org.mitre.oauth2.service.IntrospectionResultAssembler;
|
||||
|
@ -35,6 +32,8 @@ import org.springframework.stereotype.Service;
|
|||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link IntrospectionResultAssembler} interface.
|
||||
*/
|
||||
|
|
|
@ -19,7 +19,15 @@
|
|||
*/
|
||||
package org.mitre.oauth2.service.impl;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import org.mitre.oauth2.model.AuthenticationHolderEntity;
|
||||
import org.mitre.oauth2.model.AuthorizationCodeEntity;
|
||||
import org.mitre.oauth2.repository.AuthenticationHolderRepository;
|
||||
import org.mitre.oauth2.repository.AuthorizationCodeRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
|
@ -27,6 +35,7 @@ import org.springframework.security.oauth2.common.util.RandomValueStringGenerato
|
|||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Database-backed, random-value authorization code service implementation.
|
||||
|
@ -34,11 +43,18 @@ import org.springframework.stereotype.Service;
|
|||
* @author aanganes
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
@Service("defaultOAuth2AuthorizationCodeService")
|
||||
public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeServices {
|
||||
// Logger for this class
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultOAuth2AuthorizationCodeService.class);
|
||||
|
||||
@Autowired
|
||||
private AuthorizationCodeRepository repository;
|
||||
|
||||
@Autowired
|
||||
private AuthenticationHolderRepository authenticationHolderRepository;
|
||||
|
||||
private int authCodeExpirationSeconds = 60 * 5; // expire in 5 minutes by default
|
||||
|
||||
private RandomValueStringGenerator generator = new RandomValueStringGenerator();
|
||||
|
||||
|
@ -54,7 +70,15 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
public String createAuthorizationCode(OAuth2Authentication authentication) {
|
||||
String code = generator.generate();
|
||||
|
||||
AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authentication);
|
||||
// attach the authorization so that we can look it up later
|
||||
AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity();
|
||||
authHolder.setAuthentication(authentication);
|
||||
authHolder = authenticationHolderRepository.save(authHolder);
|
||||
|
||||
// set the auth code to expire
|
||||
Date expiration = new Date(System.currentTimeMillis() + (getAuthCodeExpirationSeconds() * 1000L));
|
||||
|
||||
AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authHolder, expiration);
|
||||
repository.save(entity);
|
||||
|
||||
return code;
|
||||
|
@ -73,9 +97,34 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
@Override
|
||||
public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException {
|
||||
|
||||
OAuth2Authentication auth = repository.consume(code);
|
||||
AuthorizationCodeEntity result = repository.getByCode(code);
|
||||
|
||||
if (result == null) {
|
||||
throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code);
|
||||
}
|
||||
|
||||
OAuth2Authentication auth = result.getAuthenticationHolder().getAuthentication();
|
||||
|
||||
repository.remove(result);
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and remove all expired auth codes.
|
||||
*/
|
||||
@Transactional
|
||||
public void clearExpiredAuthorizationCodes() {
|
||||
|
||||
Collection<AuthorizationCodeEntity> codes = repository.getExpiredCodes();
|
||||
|
||||
for (AuthorizationCodeEntity code : codes) {
|
||||
repository.remove(code);
|
||||
}
|
||||
|
||||
logger.info("Removed " + codes.size() + " expired authorization codes.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the repository
|
||||
|
@ -91,4 +140,18 @@ public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeS
|
|||
this.repository = repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the authCodeExpirationSeconds
|
||||
*/
|
||||
public int getAuthCodeExpirationSeconds() {
|
||||
return authCodeExpirationSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authCodeExpirationSeconds the authCodeExpirationSeconds to set
|
||||
*/
|
||||
public void setAuthCodeExpirationSeconds(int authCodeExpirationSeconds) {
|
||||
this.authCodeExpirationSeconds = authCodeExpirationSeconds;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.model.SystemScope;
|
||||
|
|
|
@ -26,10 +26,12 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
|
||||
import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
@ -124,10 +126,10 @@ public class TokenApiView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
@ -137,7 +139,7 @@ public class TokenApiView extends AbstractView {
|
|||
try {
|
||||
|
||||
Writer out = response.getWriter();
|
||||
Object obj = model.get("entity");
|
||||
Object obj = model.get(JsonEntityView.ENTITY);
|
||||
gson.toJson(obj, out);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -38,11 +38,15 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
|
@ -54,6 +58,11 @@ import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope;
|
|||
@Controller
|
||||
public class IntrospectionEndpoint {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String URL = "introspect";
|
||||
|
||||
@Autowired
|
||||
private OAuth2TokenEntityService tokenServices;
|
||||
|
||||
|
@ -69,6 +78,9 @@ public class IntrospectionEndpoint {
|
|||
@Autowired
|
||||
private ResourceSetService resourceSetService;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -82,7 +94,7 @@ public class IntrospectionEndpoint {
|
|||
this.tokenServices = tokenServices;
|
||||
}
|
||||
|
||||
@RequestMapping("/introspect")
|
||||
@RequestMapping("/" + URL)
|
||||
public String verify(@RequestParam("token") String tokenValue,
|
||||
@RequestParam(value = "token_type_hint", required = false) String tokenType,
|
||||
Authentication auth, Model model) {
|
||||
|
@ -141,7 +153,7 @@ public class IntrospectionEndpoint {
|
|||
if (Strings.isNullOrEmpty(tokenValue)) {
|
||||
logger.error("Verify failed; token value is null");
|
||||
Map<String,Boolean> entity = ImmutableMap.of("active", Boolean.FALSE);
|
||||
model.addAttribute("entity", entity);
|
||||
model.addAttribute(JsonEntityView.ENTITY, entity);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -176,8 +188,8 @@ public class IntrospectionEndpoint {
|
|||
|
||||
} catch (InvalidTokenException e2) {
|
||||
logger.error("Invalid refresh token");
|
||||
Map<String,Boolean> entity = ImmutableMap.of("active", Boolean.FALSE);
|
||||
model.addAttribute("entity", entity);
|
||||
Map<String,Boolean> entity = ImmutableMap.of(IntrospectionResultAssembler.ACTIVE, Boolean.FALSE);
|
||||
model.addAttribute(JsonEntityView.ENTITY, entity);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
@ -186,20 +198,27 @@ public class IntrospectionEndpoint {
|
|||
|
||||
if (accessToken != null) {
|
||||
Map<String, Object> entity = introspectionResultAssembler.assembleFrom(accessToken, user, authScopes);
|
||||
model.addAttribute("entity", entity);
|
||||
model.addAttribute(JsonEntityView.ENTITY, entity);
|
||||
} else if (refreshToken != null) {
|
||||
Map<String, Object> entity = introspectionResultAssembler.assembleFrom(refreshToken, user, authScopes);
|
||||
model.addAttribute("entity", entity);
|
||||
model.addAttribute(JsonEntityView.ENTITY, entity);
|
||||
} else {
|
||||
// no tokens were found (we shouldn't get here)
|
||||
logger.error("Verify failed; Invalid access/refresh token");
|
||||
Map<String,Boolean> entity = ImmutableMap.of("active", Boolean.FALSE);
|
||||
model.addAttribute("entity", entity);
|
||||
Map<String,Boolean> entity = ImmutableMap.of(IntrospectionResultAssembler.ACTIVE, Boolean.FALSE);
|
||||
model.addAttribute(JsonEntityView.ENTITY, entity);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
package org.mitre.oauth2.web;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -56,6 +54,12 @@ import com.google.common.base.Strings;
|
|||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.CSRF;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_CONSENT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_NONE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -105,7 +109,7 @@ public class OAuthConfirmationController {
|
|||
if (prompts.contains(PROMPT_NONE)) {
|
||||
// we're not supposed to prompt, so "return an error"
|
||||
logger.info("Client requested no prompt, returning 403 from confirmation endpoint");
|
||||
model.put("code", HttpStatus.FORBIDDEN);
|
||||
model.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -121,17 +125,17 @@ public class OAuthConfirmationController {
|
|||
client = clientService.loadClientByClientId(authRequest.getClientId());
|
||||
} catch (OAuth2Exception e) {
|
||||
logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client", e);
|
||||
model.put("code", HttpStatus.BAD_REQUEST);
|
||||
model.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("confirmAccess: IllegalArgumentException was thrown when attempting to load client", e);
|
||||
model.put("code", HttpStatus.BAD_REQUEST);
|
||||
model.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (client == null) {
|
||||
logger.error("confirmAccess: could not find client " + authRequest.getClientId());
|
||||
model.put("code", HttpStatus.NOT_FOUND);
|
||||
model.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,10 @@ public class RevocationEndpoint {
|
|||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class);
|
||||
|
||||
public static final String URL = "revoke";
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
|
||||
@RequestMapping("/revoke")
|
||||
@RequestMapping("/" + URL)
|
||||
public String revoke(@RequestParam("token") String tokenValue, @RequestParam(value = "token_type_hint", required = false) String tokenType, Principal principal, Model model) {
|
||||
|
||||
// This is the token as passed in from OAuth (in case we need it some day)
|
||||
|
@ -66,14 +68,14 @@ public class RevocationEndpoint {
|
|||
// client acting on its own, make sure it owns the token
|
||||
if (!accessToken.getClient().getClientId().equals(authRequest.getClientId())) {
|
||||
// trying to revoke a token we don't own, throw a 403
|
||||
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// if we got this far, we're allowed to do this
|
||||
tokenServices.revokeAccessToken(accessToken);
|
||||
model.addAttribute("code", HttpStatus.OK);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.OK);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
|
||||
} catch (InvalidTokenException e) {
|
||||
|
@ -86,21 +88,21 @@ public class RevocationEndpoint {
|
|||
// client acting on its own, make sure it owns the token
|
||||
if (!refreshToken.getClient().getClientId().equals(authRequest.getClientId())) {
|
||||
// trying to revoke a token we don't own, throw a 403
|
||||
model.addAttribute("code", HttpStatus.FORBIDDEN);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// if we got this far, we're allowed to do this
|
||||
tokenServices.revokeRefreshToken(refreshToken);
|
||||
model.addAttribute("code", HttpStatus.OK);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.OK);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
|
||||
} catch (InvalidTokenException e1) {
|
||||
|
||||
// neither token type was found, simply say "OK" and be on our way.
|
||||
|
||||
model.addAttribute("code", HttpStatus.OK);
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.OK);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,19 @@ import org.mitre.oauth2.service.SystemScopeService;
|
|||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.openid.connect.web.RootController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -45,13 +51,18 @@ import com.google.gson.Gson;
|
|||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/api/scopes")
|
||||
@RequestMapping("/" + ScopeAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class ScopeAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/scopes";
|
||||
|
||||
@Autowired
|
||||
private SystemScopeService scopeService;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -59,38 +70,38 @@ public class ScopeAPI {
|
|||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAll(ModelMap m) {
|
||||
|
||||
Set<SystemScope> allScopes = scopeService.getAll();
|
||||
|
||||
m.put("entity", allScopes);
|
||||
m.put(JsonEntityView.ENTITY, allScopes);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getScope(@PathVariable("id") Long id, ModelMap m) {
|
||||
|
||||
SystemScope scope = scopeService.getById(id);
|
||||
|
||||
if (scope != null) {
|
||||
|
||||
m.put("entity", scope);
|
||||
m.put(JsonEntityView.ENTITY, scope);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
} else {
|
||||
|
||||
logger.error("getScope failed; scope not found: " + id);
|
||||
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested scope with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested scope with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) {
|
||||
|
||||
SystemScope existing = scopeService.getById(id);
|
||||
|
@ -104,7 +115,7 @@ public class ScopeAPI {
|
|||
|
||||
scope = scopeService.save(scope);
|
||||
|
||||
m.put("entity", scope);
|
||||
m.put(JsonEntityView.ENTITY, scope);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
} else {
|
||||
|
@ -112,8 +123,8 @@ public class ScopeAPI {
|
|||
logger.error("updateScope failed; scope ids to not match: got "
|
||||
+ existing.getId() + " and " + scope.getId());
|
||||
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not update scope. Scope ids to not match: got "
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not update scope. Scope ids to not match: got "
|
||||
+ existing.getId() + " and " + scope.getId());
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
@ -121,14 +132,14 @@ public class ScopeAPI {
|
|||
} else {
|
||||
|
||||
logger.error("updateScope failed; scope with id " + id + " not found.");
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not update scope. The scope with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not update scope. The scope with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json", consumes = "application/json")
|
||||
@RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String createScope(@RequestBody String json, ModelMap m) {
|
||||
SystemScope scope = gson.fromJson(json, SystemScope.class);
|
||||
|
||||
|
@ -136,8 +147,8 @@ public class ScopeAPI {
|
|||
if (alreadyExists != null) {
|
||||
//Error, cannot save a scope with the same value as an existing one
|
||||
logger.error("Error: attempting to save a scope with a value that already exists: " + scope.getValue());
|
||||
m.put("code", HttpStatus.CONFLICT);
|
||||
m.put("errorMessage", "A scope with value " + scope.getValue() + " already exists, please choose a different value.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.CONFLICT);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "A scope with value " + scope.getValue() + " already exists, please choose a different value.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -145,14 +156,14 @@ public class ScopeAPI {
|
|||
|
||||
if (scope != null && scope.getId() != null) {
|
||||
|
||||
m.put("entity", scope);
|
||||
m.put(JsonEntityView.ENTITY, scope);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
} else {
|
||||
|
||||
logger.error("createScope failed; JSON was invalid: " + json);
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not save new scope " + scope + ". The scope service failed to return a saved entity.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not save new scope " + scope + ". The scope service failed to return a saved entity.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
|
||||
}
|
||||
|
@ -171,10 +182,15 @@ public class ScopeAPI {
|
|||
} else {
|
||||
|
||||
logger.error("deleteScope failed; scope with id " + id + " not found.");
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not delete scope. The requested scope with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not delete scope. The requested scope with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,14 +28,21 @@ import org.mitre.oauth2.service.OAuth2TokenEntityService;
|
|||
import org.mitre.oauth2.view.TokenApiView;
|
||||
import org.mitre.openid.connect.service.OIDCTokenService;
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.openid.connect.web.RootController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
@ -46,10 +53,12 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
|||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/api/tokens")
|
||||
@RequestMapping("/" + TokenAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class TokenAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/tokens";
|
||||
|
||||
@Autowired
|
||||
private OAuth2TokenEntityService tokenService;
|
||||
|
||||
|
@ -59,54 +68,57 @@ public class TokenAPI {
|
|||
@Autowired
|
||||
private OIDCTokenService oidcTokenService;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(TokenAPI.class);
|
||||
|
||||
@RequestMapping(value = "/access", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/access", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAllAccessTokens(ModelMap m, Principal p) {
|
||||
|
||||
Set<OAuth2AccessTokenEntity> allTokens = tokenService.getAllAccessTokensForUser(p.getName());
|
||||
m.put("entity", allTokens);
|
||||
m.put(JsonEntityView.ENTITY, allTokens);
|
||||
return TokenApiView.VIEWNAME;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/access/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/access/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAccessTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) {
|
||||
|
||||
OAuth2AccessTokenEntity token = tokenService.getAccessTokenById(id);
|
||||
|
||||
if (token == null) {
|
||||
logger.error("getToken failed; token not found: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested token with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) {
|
||||
logger.error("getToken failed; token does not belong to principal " + p.getName());
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to view this token");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
m.put("entity", token);
|
||||
m.put(JsonEntityView.ENTITY, token);
|
||||
return TokenApiView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/access/{id}", method = RequestMethod.DELETE, produces = "application/json")
|
||||
@RequestMapping(value = "/access/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String deleteAccessTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) {
|
||||
|
||||
OAuth2AccessTokenEntity token = tokenService.getAccessTokenById(id);
|
||||
|
||||
if (token == null) {
|
||||
logger.error("getToken failed; token not found: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested token with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) {
|
||||
logger.error("getToken failed; token does not belong to principal " + p.getName());
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to view this token");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
tokenService.revokeAccessToken(token);
|
||||
|
@ -116,26 +128,26 @@ public class TokenAPI {
|
|||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/client/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/client/{clientId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAccessTokensByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
|
||||
if (client != null) {
|
||||
List<OAuth2AccessTokenEntity> tokens = tokenService.getAccessTokensForClient(client);
|
||||
m.put("entity", tokens);
|
||||
m.put(JsonEntityView.ENTITY, tokens);
|
||||
return TokenApiView.VIEWNAME;
|
||||
} else {
|
||||
// client not found
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
|
@ -143,24 +155,24 @@ public class TokenAPI {
|
|||
if (client != null) {
|
||||
OAuth2AccessTokenEntity token = tokenService.getRegistrationAccessTokenForClient(client);
|
||||
if (token != null) {
|
||||
m.put("entity", token);
|
||||
m.put(JsonEntityView.ENTITY, token);
|
||||
return TokenApiView.VIEWNAME;
|
||||
} else {
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "No registration token could be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "No registration token could be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
} else {
|
||||
// client not found
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.PUT, produces = "application/json")
|
||||
@RequestMapping(value = "/registration/{clientId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String rotateRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) {
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
|
||||
|
@ -169,67 +181,67 @@ public class TokenAPI {
|
|||
token = tokenService.saveAccessToken(token);
|
||||
|
||||
if (token != null) {
|
||||
m.put("entity", token);
|
||||
m.put(JsonEntityView.ENTITY, token);
|
||||
return TokenApiView.VIEWNAME;
|
||||
} else {
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "No registration token could be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "No registration token could be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
} else {
|
||||
// client not found
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested client with id " + clientId + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAllRefreshTokens(ModelMap m, Principal p) {
|
||||
|
||||
Set<OAuth2RefreshTokenEntity> allTokens = tokenService.getAllRefreshTokensForUser(p.getName());
|
||||
m.put("entity", allTokens);
|
||||
m.put(JsonEntityView.ENTITY, allTokens);
|
||||
return TokenApiView.VIEWNAME;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/refresh/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/refresh/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getRefreshTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) {
|
||||
|
||||
OAuth2RefreshTokenEntity token = tokenService.getRefreshTokenById(id);
|
||||
|
||||
if (token == null) {
|
||||
logger.error("refresh token not found: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested token with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) {
|
||||
logger.error("refresh token " + id + " does not belong to principal " + p.getName());
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to view this token");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
m.put("entity", token);
|
||||
m.put(JsonEntityView.ENTITY, token);
|
||||
return TokenApiView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/refresh/{id}", method = RequestMethod.DELETE, produces = "application/json")
|
||||
@RequestMapping(value = "/refresh/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String deleteRefreshTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) {
|
||||
|
||||
OAuth2RefreshTokenEntity token = tokenService.getRefreshTokenById(id);
|
||||
|
||||
if (token == null) {
|
||||
logger.error("refresh token not found: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested token with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) {
|
||||
logger.error("refresh token " + id + " does not belong to principal " + p.getName());
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to view this token");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
tokenService.revokeRefreshToken(token);
|
||||
|
@ -238,4 +250,9 @@ public class TokenAPI {
|
|||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,23 @@ package org.mitre.openid.connect.assertion;
|
|||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.mockito.AdditionalMatchers;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.oauth2.common.exceptions.BadClientCredentialsException;
|
||||
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter;
|
||||
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.nimbusds.jwt.JWT;
|
||||
|
@ -41,14 +50,34 @@ import com.nimbusds.jwt.JWTParser;
|
|||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public class JWTBearerClientAssertionTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
|
||||
public class JWTBearerClientAssertionTokenEndpointFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
public JWTBearerClientAssertionTokenEndpointFilter() {
|
||||
super();
|
||||
private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
|
||||
|
||||
public JWTBearerClientAssertionTokenEndpointFilter(RequestMatcher additionalMatcher) {
|
||||
super(new ClientAssertionRequestMatcher(additionalMatcher));
|
||||
// If authentication fails the type is "Form"
|
||||
((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setTypeName("Form");
|
||||
}
|
||||
|
||||
public JWTBearerClientAssertionTokenEndpointFilter(String path) {
|
||||
super(path);
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException, ServletException {
|
||||
if (exception instanceof BadCredentialsException) {
|
||||
exception = new BadCredentialsException(exception.getMessage(), new BadClientCredentialsException());
|
||||
}
|
||||
authenticationEntryPoint.commence(request, response, exception);
|
||||
}
|
||||
});
|
||||
setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authentication) throws IOException, ServletException {
|
||||
// no-op - just allow filter chain to continue to token endpoint
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,42 +103,38 @@ public class JWTBearerClientAssertionTokenEndpointFilter extends ClientCredentia
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the "client_assertion_type" and "client_assertion" parameters are present and contain the right values.
|
||||
*/
|
||||
@Override
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
String assertion = request.getParameter("client_assertion");
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain chain, Authentication authResult) throws IOException, ServletException {
|
||||
super.successfulAuthentication(request, response, chain, authResult);
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) {
|
||||
return false;
|
||||
} else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) {
|
||||
return false;
|
||||
private static class ClientAssertionRequestMatcher implements RequestMatcher {
|
||||
|
||||
private RequestMatcher additionalMatcher;
|
||||
|
||||
public ClientAssertionRequestMatcher(RequestMatcher additionalMatcher) {
|
||||
this.additionalMatcher = additionalMatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
// check for appropriate parameters
|
||||
String assertionType = request.getParameter("client_assertion_type");
|
||||
String assertion = request.getParameter("client_assertion");
|
||||
|
||||
|
||||
// Can't call to superclass here b/c client creds would break for lack of client_id
|
||||
// return super.requiresAuthentication(request, response);
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
int pathParamIndex = uri.indexOf(';');
|
||||
|
||||
if (pathParamIndex > 0) {
|
||||
// strip everything after the first semi-colon
|
||||
uri = uri.substring(0, pathParamIndex);
|
||||
if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) {
|
||||
return false;
|
||||
} else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return additionalMatcher.matches(request);
|
||||
}
|
||||
|
||||
if ("".equals(request.getContextPath())) {
|
||||
return uri.endsWith(getFilterProcessesUrl());
|
||||
}
|
||||
|
||||
return uri.endsWith(request.getContextPath() + getFilterProcessesUrl());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2015 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.openid.connect.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.support.AbstractMessageSource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public class JsonMessageSource extends AbstractMessageSource {
|
||||
// Logger for this class
|
||||
private static final Logger logger = LoggerFactory.getLogger(JsonMessageSource.class);
|
||||
|
||||
private Resource baseDirectory;
|
||||
|
||||
private Locale fallbackLocale = new Locale("en"); // US English is the fallback language
|
||||
|
||||
private Map<Locale, JsonObject> languageMaps = new HashMap<>();
|
||||
|
||||
@Override
|
||||
protected MessageFormat resolveCode(String code, Locale locale) {
|
||||
|
||||
JsonObject lang = getLanguageMap(locale);
|
||||
|
||||
String value = getValue(code, lang);
|
||||
|
||||
if (value == null) {
|
||||
// if we haven't found anything, try the default locale
|
||||
lang = getLanguageMap(fallbackLocale);
|
||||
value = getValue(code, lang);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
value = code;
|
||||
}
|
||||
|
||||
MessageFormat mf = new MessageFormat(value, locale);
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param code
|
||||
* @param locale
|
||||
* @param lang
|
||||
* @return
|
||||
*/
|
||||
private String getValue(String code, JsonObject lang) {
|
||||
|
||||
// if there's no language map, nothing to look up
|
||||
if (lang == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JsonElement e = lang;
|
||||
|
||||
Iterable<String> parts = Splitter.on('.').split(code);
|
||||
Iterator<String> it = parts.iterator();
|
||||
|
||||
String value = null;
|
||||
|
||||
while (it.hasNext()) {
|
||||
String p = it.next();
|
||||
if (e.isJsonObject()) {
|
||||
JsonObject o = e.getAsJsonObject();
|
||||
if (o.has(p)) {
|
||||
e = o.get(p); // found the next level
|
||||
if (!it.hasNext()) {
|
||||
// we've reached a leaf, grab it
|
||||
if (e.isJsonPrimitive()) {
|
||||
value = e.getAsString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// didn't find it, stop processing
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// didn't find it, stop processing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
private JsonObject getLanguageMap(Locale locale) {
|
||||
|
||||
if (!languageMaps.containsKey(locale)) {
|
||||
try {
|
||||
String filename = locale.getLanguage() + File.separator + "messages.json";
|
||||
|
||||
Resource r = getBaseDirectory().createRelative(filename);
|
||||
|
||||
logger.info("No locale loaded, trying to load from " + r);
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(new InputStreamReader(r.getInputStream(), "UTF-8"));
|
||||
|
||||
languageMaps.put(locale, obj);
|
||||
} catch (JsonIOException | JsonSyntaxException | IOException e) {
|
||||
logger.error("Unable to load locale", e);
|
||||
}
|
||||
}
|
||||
|
||||
return languageMaps.get(locale);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the baseDirectory
|
||||
*/
|
||||
public Resource getBaseDirectory() {
|
||||
return baseDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param baseDirectory the baseDirectory to set
|
||||
*/
|
||||
public void setBaseDirectory(Resource baseDirectory) {
|
||||
this.baseDirectory = baseDirectory;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,9 +19,8 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.filter;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -35,6 +34,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.mitre.oauth2.model.ClientDetailsEntity;
|
||||
import org.mitre.oauth2.service.ClientDetailsEntityService;
|
||||
import org.mitre.openid.connect.web.AuthenticationTimeStamper;
|
||||
|
@ -46,12 +46,20 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
|
||||
import org.springframework.security.oauth2.provider.AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
|
||||
import org.springframework.security.oauth2.provider.endpoint.RedirectResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_LOGIN;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_NONE;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -72,6 +80,9 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
|
|||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
@Autowired
|
||||
private RedirectResolver redirectResolver;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -114,7 +125,7 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
|
|||
if (authRequest.getExtensions().get(PROMPT) != null) {
|
||||
// we have a "prompt" parameter
|
||||
String prompt = (String)authRequest.getExtensions().get(PROMPT);
|
||||
List<String> prompts = Splitter.on(" ").splitToList(Strings.nullToEmpty(prompt));
|
||||
List<String> prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt));
|
||||
|
||||
if (prompts.contains(PROMPT_NONE)) {
|
||||
logger.info("Client requested no prompt");
|
||||
|
@ -127,7 +138,32 @@ public class AuthorizationRequestFilter extends GenericFilterBean {
|
|||
chain.doFilter(req, res);
|
||||
} else {
|
||||
// user hasn't been logged in, we need to "return an error"
|
||||
logger.info("User not logged in, no prompt requested, returning 403 from filter");
|
||||
logger.info("User not logged in, no prompt requested, returning error from filter");
|
||||
|
||||
if (client != null && authRequest.getRedirectUri() != null) {
|
||||
|
||||
// if we've got a redirect URI then we'll send it
|
||||
|
||||
String url = redirectResolver.resolveRedirect(authRequest.getRedirectUri(), client);
|
||||
|
||||
try {
|
||||
URIBuilder uriBuilder = new URIBuilder(url);
|
||||
|
||||
uriBuilder.addParameter(ERROR, LOGIN_REQUIRED);
|
||||
if (!Strings.isNullOrEmpty(authRequest.getState())) {
|
||||
uriBuilder.addParameter(STATE, authRequest.getState()); // copy the state parameter if one was given
|
||||
}
|
||||
|
||||
response.sendRedirect(uriBuilder.toString());
|
||||
return;
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
logger.error("Can't build redirect URI for prompt=none, sending error instead", e);
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2015 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.openid.connect.filter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
public class MultiUrlRequestMatcher implements RequestMatcher {
|
||||
private final Set<String> filterProcessesUrls;
|
||||
|
||||
public MultiUrlRequestMatcher(Set<String> filterProcessesUrls) {
|
||||
for (String filterProcessesUrl : filterProcessesUrls) {
|
||||
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
|
||||
Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
|
||||
}
|
||||
this.filterProcessesUrls = ImmutableSet.copyOf(filterProcessesUrls);
|
||||
}
|
||||
|
||||
public boolean matches(HttpServletRequest request) {
|
||||
String uri = request.getRequestURI();
|
||||
int pathParamIndex = uri.indexOf(';');
|
||||
|
||||
if (pathParamIndex > 0) {
|
||||
// strip everything after the first semi-colon
|
||||
uri = uri.substring(0, pathParamIndex);
|
||||
}
|
||||
|
||||
if ("".equals(request.getContextPath())) {
|
||||
// if any one of the URLs match, return true
|
||||
for (String filterProcessesUrl : filterProcessesUrls) {
|
||||
if (uri.endsWith(filterProcessesUrl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String filterProcessesUrl : filterProcessesUrls) {
|
||||
if (uri.endsWith(request.getContextPath() + filterProcessesUrl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
@ -29,6 +27,8 @@ import org.mitre.openid.connect.repository.ApprovedSiteRepository;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* JPA ApprovedSite repository implementation
|
||||
*
|
||||
|
@ -44,8 +44,7 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<ApprovedSite> getAll() {
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(
|
||||
"ApprovedSite.getAll", ApprovedSite.class);
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(ApprovedSite.QUERY_ALL, ApprovedSite.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
@ -76,9 +75,9 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
@Override
|
||||
public Collection<ApprovedSite> getByClientIdAndUserId(String clientId, String userId) {
|
||||
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class);
|
||||
query.setParameter("userId", userId);
|
||||
query.setParameter("clientId", clientId);
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(ApprovedSite.QUERY_BY_CLIENT_ID_AND_USER_ID, ApprovedSite.class);
|
||||
query.setParameter(ApprovedSite.PARAM_USER_ID, userId);
|
||||
query.setParameter(ApprovedSite.PARAM_CLIENT_ID, clientId);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
@ -86,8 +85,8 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<ApprovedSite> getByUserId(String userId) {
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByUserId", ApprovedSite.class);
|
||||
query.setParameter("userId", userId);
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(ApprovedSite.QUERY_BY_USER_ID, ApprovedSite.class);
|
||||
query.setParameter(ApprovedSite.PARAM_USER_ID, userId);
|
||||
|
||||
return query.getResultList();
|
||||
|
||||
|
@ -96,8 +95,8 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<ApprovedSite> getByClientId(String clientId) {
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientId", ApprovedSite.class);
|
||||
query.setParameter("clientId", clientId);
|
||||
TypedQuery<ApprovedSite> query = manager.createNamedQuery(ApprovedSite.QUERY_BY_CLIENT_ID, ApprovedSite.class);
|
||||
query.setParameter(ApprovedSite.PARAM_CLIENT_ID, clientId);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
@ -32,6 +30,8 @@ import org.mitre.openid.connect.repository.BlacklistedSiteRepository;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -48,7 +48,7 @@ public class JpaBlacklistedSiteRepository implements BlacklistedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<BlacklistedSite> getAll() {
|
||||
TypedQuery<BlacklistedSite> query = manager.createNamedQuery("BlacklistedSite.getAll", BlacklistedSite.class);
|
||||
TypedQuery<BlacklistedSite> query = manager.createNamedQuery(BlacklistedSite.QUERY_ALL, BlacklistedSite.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
*/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
@ -31,6 +28,9 @@ import org.mitre.openid.connect.repository.PairwiseIdentifierRepository;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -46,9 +46,9 @@ public class JpaPairwiseIdentifierRepository implements PairwiseIdentifierReposi
|
|||
*/
|
||||
@Override
|
||||
public PairwiseIdentifier getBySectorIdentifier(String sub, String sectorIdentifierUri) {
|
||||
TypedQuery<PairwiseIdentifier> query = manager.createNamedQuery("PairwiseIdentifier.getBySectorIdentifier", PairwiseIdentifier.class);
|
||||
query.setParameter("sub", sub);
|
||||
query.setParameter("sectorIdentifier", sectorIdentifierUri);
|
||||
TypedQuery<PairwiseIdentifier> query = manager.createNamedQuery(PairwiseIdentifier.QUERY_BY_SECTOR_IDENTIFIER, PairwiseIdentifier.class);
|
||||
query.setParameter(PairwiseIdentifier.PARAM_SUB, sub);
|
||||
query.setParameter(PairwiseIdentifier.PARAM_SECTOR_IDENTIFIER, sectorIdentifierUri);
|
||||
|
||||
return getSingleResult(query.getResultList());
|
||||
}
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
@ -27,7 +24,8 @@ import org.mitre.openid.connect.model.DefaultUserInfo;
|
|||
import org.mitre.openid.connect.model.UserInfo;
|
||||
import org.mitre.openid.connect.repository.UserInfoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.getSingleResult;
|
||||
|
||||
/**
|
||||
* JPA UserInfo repository implementation
|
||||
|
@ -46,8 +44,8 @@ public class JpaUserInfoRepository implements UserInfoRepository {
|
|||
*/
|
||||
@Override
|
||||
public UserInfo getByUsername(String username) {
|
||||
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery("DefaultUserInfo.getByUsername", DefaultUserInfo.class);
|
||||
query.setParameter("username", username);
|
||||
TypedQuery<DefaultUserInfo> query = manager.createNamedQuery(DefaultUserInfo.QUERY_BY_USERNAME, DefaultUserInfo.class);
|
||||
query.setParameter(DefaultUserInfo.PARAM_USERNAME, username);
|
||||
|
||||
return getSingleResult(query.getResultList());
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.repository.impl;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
@ -30,6 +28,8 @@ import org.mitre.util.jpa.JpaUtil;
|
|||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
|
||||
|
||||
/**
|
||||
* JPA WhitelistedSite repository implementation
|
||||
*
|
||||
|
@ -45,7 +45,7 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<WhitelistedSite> getAll() {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getAll", WhitelistedSite.class);
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery(WhitelistedSite.QUERY_ALL, WhitelistedSite.class);
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
@ -85,16 +85,16 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
|
|||
@Override
|
||||
@Transactional
|
||||
public WhitelistedSite getByClientId(String clientId) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByClientId", WhitelistedSite.class);
|
||||
query.setParameter("clientId", clientId);
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery(WhitelistedSite.QUERY_BY_CLIENT_ID, WhitelistedSite.class);
|
||||
query.setParameter(WhitelistedSite.PARAM_CLIENT_ID, clientId);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<WhitelistedSite> getByCreator(String creatorId) {
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByCreaterUserId", WhitelistedSite.class);
|
||||
query.setParameter("userId", creatorId);
|
||||
TypedQuery<WhitelistedSite> query = manager.createNamedQuery(WhitelistedSite.QUERY_BY_CREATOR, WhitelistedSite.class);
|
||||
query.setParameter(WhitelistedSite.PARAM_USER_ID, creatorId);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.request;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
@ -55,6 +53,19 @@ import com.nimbusds.jwt.PlainJWT;
|
|||
import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLAIMS;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.CLIENT_ID;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.CSRF;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.DISPLAY;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_HINT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.NONCE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.REDIRECT_URI;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.REQUEST;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.RESPONSE_TYPE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.STATE;
|
||||
|
||||
@Component("connectOAuth2RequestFactory")
|
||||
public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory {
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ public interface ConnectRequestParameters {
|
|||
public String CSRF = "csrf";
|
||||
public String APPROVED_SITE = "approved_site";
|
||||
|
||||
|
||||
// responses
|
||||
public String ERROR = "error";
|
||||
public String LOGIN_REQUIRED = "login_required";
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.service.impl;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
|
@ -66,6 +62,10 @@ import com.google.common.collect.Sets;
|
|||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
/**
|
||||
*
|
||||
* Data service to import MITREid 1.0 configuration.
|
||||
|
|
|
@ -16,10 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.service.impl;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.text.ParseException;
|
||||
|
@ -69,6 +65,10 @@ import com.google.gson.stream.JsonReader;
|
|||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data service to import MITREid 1.1 configuration.
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.service.impl;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.base64UrlEncodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
import static org.mitre.util.JsonUtils.writeNullSafeArray;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.text.ParseException;
|
||||
|
@ -71,6 +65,12 @@ import com.google.gson.stream.JsonReader;
|
|||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import static org.mitre.util.JsonUtils.base64UrlDecodeObject;
|
||||
import static org.mitre.util.JsonUtils.base64UrlEncodeObject;
|
||||
import static org.mitre.util.JsonUtils.readMap;
|
||||
import static org.mitre.util.JsonUtils.readSet;
|
||||
import static org.mitre.util.JsonUtils.writeNullSafeArray;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data service to import and export MITREid 1.2 configuration.
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*******************************************************************************/
|
||||
package org.mitre.openid.connect.token;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
@ -49,6 +47,11 @@ import com.google.common.base.Splitter;
|
|||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.APPROVED_SITE;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.CSRF;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT;
|
||||
import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Custom User Approval Handler implementation which uses a concept of a whitelist,
|
||||
* blacklist, and greylist.
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.mitre.jose.JWSAlgorithmEmbed;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
|
@ -105,10 +106,10 @@ public abstract class AbstractClientEntityView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ public abstract class AbstractClientEntityView extends AbstractView {
|
|||
try {
|
||||
|
||||
Writer out = response.getWriter();
|
||||
Object obj = model.get("entity");
|
||||
Object obj = model.get(JsonEntityView.ENTITY);
|
||||
gson.toJson(obj, out);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
|
@ -65,13 +66,13 @@ public class ClientInformationResponseView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
RegisteredClient c = (RegisteredClient) model.get("client");
|
||||
//OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) model.get("token");
|
||||
//String uri = (String)model.get("uri"); //request.getRequestURL() + "/" + c.getClientId();
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,12 @@ import org.springframework.web.servlet.view.AbstractView;
|
|||
public class HttpCodeView extends AbstractView {
|
||||
|
||||
public static final String VIEWNAME = "httpCodeView";
|
||||
|
||||
public static final String CODE = "code";
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.mitre.openid.connect.model.WhitelistedSite;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
@ -98,10 +99,10 @@ public class JsonApprovedSiteView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
@ -111,7 +112,7 @@ public class JsonApprovedSiteView extends AbstractView {
|
|||
try {
|
||||
|
||||
Writer out = response.getWriter();
|
||||
Object obj = model.get("entity");
|
||||
Object obj = model.get(JsonEntityView.ENTITY);
|
||||
gson.toJson(obj, out);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
@ -45,6 +46,8 @@ import com.google.gson.GsonBuilder;
|
|||
@Component(JsonEntityView.VIEWNAME)
|
||||
public class JsonEntityView extends AbstractView {
|
||||
|
||||
public static final String ENTITY = "entity";
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -78,10 +81,10 @@ public class JsonEntityView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
}
|
||||
|
@ -91,7 +94,7 @@ public class JsonEntityView extends AbstractView {
|
|||
try {
|
||||
|
||||
Writer out = response.getWriter();
|
||||
Object obj = model.get("entity");
|
||||
Object obj = model.get(ENTITY);
|
||||
gson.toJson(obj, out);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
@ -44,6 +45,16 @@ import com.google.gson.JsonObject;
|
|||
@Component(JsonErrorView.VIEWNAME)
|
||||
public class JsonErrorView extends AbstractView {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String ERROR_MESSAGE = "errorMessage";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String ERROR = "error";
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -77,12 +88,12 @@ public class JsonErrorView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
HttpStatus code = (HttpStatus) model.get("code");
|
||||
HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE);
|
||||
if (code == null) {
|
||||
code = HttpStatus.OK; // default to 200
|
||||
code = HttpStatus.INTERNAL_SERVER_ERROR; // default to 500
|
||||
}
|
||||
|
||||
response.setStatus(code.value());
|
||||
|
@ -91,11 +102,11 @@ public class JsonErrorView extends AbstractView {
|
|||
|
||||
Writer out = response.getWriter();
|
||||
|
||||
String errorTitle = (String) model.get("error");
|
||||
String errorTitle = (String) model.get(ERROR);
|
||||
if (Strings.isNullOrEmpty(errorTitle)) {
|
||||
errorTitle = "Error";
|
||||
errorTitle = "mitreid_error";
|
||||
}
|
||||
String errorMessage = (String) model.get("errorMessage");
|
||||
String errorMessage = (String) model.get(ERROR_MESSAGE);
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.addProperty("error", errorTitle);
|
||||
obj.addProperty("error_description", errorMessage);
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
@ -59,6 +60,8 @@ import com.nimbusds.jwt.SignedJWT;
|
|||
@Component(UserInfoJWTView.VIEWNAME)
|
||||
public class UserInfoJWTView extends UserInfoView {
|
||||
|
||||
public static final String CLIENT = "client";
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -66,6 +69,10 @@ public class UserInfoJWTView extends UserInfoView {
|
|||
|
||||
public static final String VIEWNAME = "userInfoJwtView";
|
||||
|
||||
public static final String JOSE_MEDIA_TYPE_VALUE = "application/jwt";
|
||||
public static final MediaType JOSE_MEDIA_TYPE = new MediaType("application", "jwt");
|
||||
|
||||
|
||||
@Autowired
|
||||
private JWTSigningAndValidationService jwtService;
|
||||
|
||||
|
@ -83,13 +90,13 @@ public class UserInfoJWTView extends UserInfoView {
|
|||
HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
try {
|
||||
ClientDetailsEntity client = (ClientDetailsEntity)model.get("client");
|
||||
ClientDetailsEntity client = (ClientDetailsEntity)model.get(CLIENT);
|
||||
|
||||
// use the parser to import the user claims into the object
|
||||
StringWriter writer = new StringWriter();
|
||||
gson.toJson(json, writer);
|
||||
|
||||
response.setContentType("application/jwt");
|
||||
response.setContentType(JOSE_MEDIA_TYPE_VALUE);
|
||||
|
||||
JWTClaimsSet claims = JWTClaimsSet.parse(writer.toString());
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.mitre.openid.connect.service.ScopeClaimTranslationService;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
@ -46,9 +47,14 @@ import com.google.gson.JsonParser;
|
|||
@Component(UserInfoView.VIEWNAME)
|
||||
public class UserInfoView extends AbstractView {
|
||||
|
||||
private static JsonParser jsonParser = new JsonParser();
|
||||
public static final String REQUESTED_CLAIMS = "requestedClaims";
|
||||
public static final String AUTHORIZED_CLAIMS = "authorizedClaims";
|
||||
public static final String SCOPE = "scope";
|
||||
public static final String USER_INFO = "userInfo";
|
||||
|
||||
public static final String VIEWNAME = "userInfoView";
|
||||
|
||||
private static JsonParser jsonParser = new JsonParser();
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
|
@ -88,20 +94,20 @@ public class UserInfoView extends AbstractView {
|
|||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
UserInfo userInfo = (UserInfo) model.get("userInfo");
|
||||
UserInfo userInfo = (UserInfo) model.get(USER_INFO);
|
||||
|
||||
Set<String> scope = (Set<String>) model.get("scope");
|
||||
Set<String> scope = (Set<String>) model.get(SCOPE);
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
|
||||
JsonObject authorizedClaims = null;
|
||||
JsonObject requestedClaims = null;
|
||||
if (model.get("authorizedClaims") != null) {
|
||||
authorizedClaims = jsonParser.parse((String) model.get("authorizedClaims")).getAsJsonObject();
|
||||
if (model.get(AUTHORIZED_CLAIMS) != null) {
|
||||
authorizedClaims = jsonParser.parse((String) model.get(AUTHORIZED_CLAIMS)).getAsJsonObject();
|
||||
}
|
||||
if (model.get("requestedClaims") != null) {
|
||||
requestedClaims = jsonParser.parse((String) model.get("requestedClaims")).getAsJsonObject();
|
||||
if (model.get(REQUESTED_CLAIMS) != null) {
|
||||
requestedClaims = jsonParser.parse((String) model.get(REQUESTED_CLAIMS)).getAsJsonObject();
|
||||
}
|
||||
JsonObject json = toJsonFromRequestObj(userInfo, scope, authorizedClaims, requestedClaims);
|
||||
|
||||
|
|
|
@ -27,14 +27,20 @@ import org.mitre.openid.connect.model.ApprovedSite;
|
|||
import org.mitre.openid.connect.service.ApprovedSiteService;
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonApprovedSiteView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
@ -44,15 +50,20 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
|||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/api/approved")
|
||||
@RequestMapping("/" + ApprovedSiteAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class ApprovedSiteAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/approved";
|
||||
|
||||
@Autowired
|
||||
private ApprovedSiteService approvedSiteService;
|
||||
|
||||
@Autowired
|
||||
OAuth2TokenEntityService tokenServices;
|
||||
private OAuth2TokenEntityService tokenServices;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
|
@ -64,12 +75,12 @@ public class ApprovedSiteAPI {
|
|||
* @param m
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAllApprovedSites(ModelMap m, Principal p) {
|
||||
|
||||
Collection<ApprovedSite> all = approvedSiteService.getByUserId(p.getName());
|
||||
|
||||
m.put("entity", all);
|
||||
m.put(JsonEntityView.ENTITY, all);
|
||||
|
||||
return JsonApprovedSiteView.VIEWNAME;
|
||||
}
|
||||
|
@ -84,17 +95,17 @@ public class ApprovedSiteAPI {
|
|||
|
||||
if (approvedSite == null) {
|
||||
logger.error("deleteApprovedSite failed; no approved site found for id: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not delete approved site. The requested approved site with id: " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not delete approved site. The requested approved site with id: " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!approvedSite.getUserId().equals(p.getName())) {
|
||||
logger.error("deleteApprovedSite failed; principal "
|
||||
+ p.getName() + " does not own approved site" + id);
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to delete this approved site. The approved site decision will not be deleted.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to delete this approved site. The approved site decision will not be deleted.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
m.put("code", HttpStatus.OK);
|
||||
m.put(HttpCodeView.CODE, HttpStatus.OK);
|
||||
approvedSiteService.remove(approvedSite);
|
||||
}
|
||||
|
||||
|
@ -104,24 +115,30 @@ public class ApprovedSiteAPI {
|
|||
/**
|
||||
* Get a single approved site
|
||||
*/
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getApprovedSite(@PathVariable("id") Long id, ModelMap m, Principal p) {
|
||||
ApprovedSite approvedSite = approvedSiteService.getById(id);
|
||||
if (approvedSite == null) {
|
||||
logger.error("getApprovedSite failed; no approved site found for id: " + id);
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "The requested approved site with id: " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "The requested approved site with id: " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else if (!approvedSite.getUserId().equals(p.getName())) {
|
||||
logger.error("getApprovedSite failed; principal "
|
||||
+ p.getName() + " does not own approved site" + id);
|
||||
m.put("code", HttpStatus.FORBIDDEN);
|
||||
m.put("errorMessage", "You do not have permission to view this approved site.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this approved site.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
m.put("entity", approvedSite);
|
||||
m.put(JsonEntityView.ENTITY, approvedSite);
|
||||
return JsonApprovedSiteView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,14 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -49,10 +54,12 @@ import com.google.gson.JsonSyntaxException;
|
|||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/api/blacklist")
|
||||
@RequestMapping("/" + BlacklistAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
public class BlacklistAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/blacklist";
|
||||
|
||||
@Autowired
|
||||
private BlacklistedSiteService blacklistService;
|
||||
|
||||
|
@ -61,6 +68,9 @@ public class BlacklistAPI {
|
|||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(BlacklistAPI.class);
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
private Gson gson = new Gson();
|
||||
private JsonParser parser = new JsonParser();
|
||||
|
||||
|
@ -69,12 +79,12 @@ public class BlacklistAPI {
|
|||
* @param m
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getAllBlacklistedSites(ModelMap m) {
|
||||
|
||||
Collection<BlacklistedSite> all = blacklistService.getAll();
|
||||
|
||||
m.put("entity", all);
|
||||
m.put(JsonEntityView.ENTITY, all);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
@ -86,7 +96,7 @@ public class BlacklistAPI {
|
|||
* @param p
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String addNewBlacklistedSite(@RequestBody String jsonString, ModelMap m, Principal p) {
|
||||
|
||||
JsonObject json;
|
||||
|
@ -98,18 +108,18 @@ public class BlacklistAPI {
|
|||
json = parser.parse(jsonString).getAsJsonObject();
|
||||
blacklist = gson.fromJson(json, BlacklistedSite.class);
|
||||
BlacklistedSite newBlacklist = blacklistService.saveNew(blacklist);
|
||||
m.put("entity", newBlacklist);
|
||||
m.put(JsonEntityView.ENTITY, newBlacklist);
|
||||
|
||||
}
|
||||
catch (JsonSyntaxException e) {
|
||||
logger.error("addNewBlacklistedSite failed due to JsonSyntaxException: ", e);
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not save new blacklisted site. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not save new blacklisted site. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.error("addNewBlacklistedSite failed due to IllegalStateException", e);
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not save new blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not save new blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -120,7 +130,7 @@ public class BlacklistAPI {
|
|||
/**
|
||||
* Update an existing blacklisted site
|
||||
*/
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String updateBlacklistedSite(@PathVariable("id") Long id, @RequestBody String jsonString, ModelMap m, Principal p) {
|
||||
|
||||
JsonObject json;
|
||||
|
@ -135,13 +145,13 @@ public class BlacklistAPI {
|
|||
}
|
||||
catch (JsonSyntaxException e) {
|
||||
logger.error("updateBlacklistedSite failed due to JsonSyntaxException", e);
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not update blacklisted site. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not update blacklisted site. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.error("updateBlacklistedSite failed due to IllegalStateException", e);
|
||||
m.put("code", HttpStatus.BAD_REQUEST);
|
||||
m.put("errorMessage", "Could not update blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not update blacklisted site. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -150,14 +160,14 @@ public class BlacklistAPI {
|
|||
|
||||
if (oldBlacklist == null) {
|
||||
logger.error("updateBlacklistedSite failed; blacklist with id " + id + " could not be found");
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not update blacklisted site. The requested blacklist with id " + id + "could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not update blacklisted site. The requested blacklist with id " + id + "could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
|
||||
BlacklistedSite newBlacklist = blacklistService.update(oldBlacklist, blacklist);
|
||||
|
||||
m.put("entity", newBlacklist);
|
||||
m.put(JsonEntityView.ENTITY, newBlacklist);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
@ -173,10 +183,10 @@ public class BlacklistAPI {
|
|||
|
||||
if (blacklist == null) {
|
||||
logger.error("deleteBlacklistedSite failed; blacklist with id " + id + " could not be found");
|
||||
m.put("errorMessage", "Could not delete bladklist. The requested bladklist with id " + id + " could not be found.");
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not delete bladklist. The requested bladklist with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
m.put("code", HttpStatus.OK);
|
||||
m.put(HttpCodeView.CODE, HttpStatus.OK);
|
||||
blacklistService.remove(blacklist);
|
||||
}
|
||||
|
||||
|
@ -186,20 +196,26 @@ public class BlacklistAPI {
|
|||
/**
|
||||
* Get a single blacklisted site
|
||||
*/
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getBlacklistedSite(@PathVariable("id") Long id, ModelMap m) {
|
||||
BlacklistedSite blacklist = blacklistService.getById(id);
|
||||
if (blacklist == null) {
|
||||
logger.error("getBlacklistedSite failed; blacklist with id " + id + " could not be found");
|
||||
m.put("code", HttpStatus.NOT_FOUND);
|
||||
m.put("errorMessage", "Could not delete bladklist. The requested bladklist with id " + id + " could not be found.");
|
||||
m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.put(JsonErrorView.ERROR_MESSAGE, "Could not delete bladklist. The requested bladklist with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
|
||||
m.put("entity", blacklist);
|
||||
m.put(JsonEntityView.ENTITY, blacklist);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,22 @@ import org.mitre.openid.connect.service.UserInfoService;
|
|||
import org.mitre.openid.connect.view.ClientEntityViewForAdmins;
|
||||
import org.mitre.openid.connect.view.ClientEntityViewForUsers;
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -61,16 +68,21 @@ import com.google.gson.JsonSyntaxException;
|
|||
*/
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/api/clients")
|
||||
@RequestMapping("/" + ClientAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class ClientAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/clients";
|
||||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
@Autowired
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
private JsonParser parser = new JsonParser();
|
||||
|
||||
private Gson gson = new GsonBuilder()
|
||||
|
@ -118,11 +130,11 @@ public class ClientAPI {
|
|||
* @param modelAndView
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String apiGetAllClients(Model model, Authentication auth) {
|
||||
|
||||
Collection<ClientDetailsEntity> clients = clientService.getAllClients();
|
||||
model.addAttribute("entity", clients);
|
||||
model.addAttribute(JsonEntityView.ENTITY, clients);
|
||||
|
||||
if (AuthenticationUtilities.isAdmin(auth)) {
|
||||
return ClientEntityViewForAdmins.VIEWNAME;
|
||||
|
@ -139,7 +151,7 @@ public class ClientAPI {
|
|||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String apiAddClient(@RequestBody String jsonString, Model m, Authentication auth) {
|
||||
|
||||
JsonObject json = null;
|
||||
|
@ -151,13 +163,13 @@ public class ClientAPI {
|
|||
}
|
||||
catch (JsonSyntaxException e) {
|
||||
logger.error("apiAddClient failed due to JsonSyntaxException", e);
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Could not save new client. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Could not save new client. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.error("apiAddClient failed due to IllegalStateException", e);
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Could not save new client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Could not save new client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -186,8 +198,8 @@ public class ClientAPI {
|
|||
|
||||
if (Strings.isNullOrEmpty(client.getJwksUri())) {
|
||||
logger.error("tried to create client with private key auth but no private key");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -197,8 +209,8 @@ public class ClientAPI {
|
|||
} else {
|
||||
|
||||
logger.error("unknown auth method");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Unknown auth method requested");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Unknown auth method requested");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
|
||||
|
||||
|
@ -207,7 +219,7 @@ public class ClientAPI {
|
|||
client.setDynamicallyRegistered(false);
|
||||
|
||||
ClientDetailsEntity newClient = clientService.saveNewClient(client);
|
||||
m.addAttribute("entity", newClient);
|
||||
m.addAttribute(JsonEntityView.ENTITY, newClient);
|
||||
|
||||
if (AuthenticationUtilities.isAdmin(auth)) {
|
||||
return ClientEntityViewForAdmins.VIEWNAME;
|
||||
|
@ -225,7 +237,7 @@ public class ClientAPI {
|
|||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(value="/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String apiUpdateClient(@PathVariable("id") Long id, @RequestBody String jsonString, Model m, Authentication auth) {
|
||||
|
||||
JsonObject json = null;
|
||||
|
@ -238,13 +250,13 @@ public class ClientAPI {
|
|||
}
|
||||
catch (JsonSyntaxException e) {
|
||||
logger.error("apiUpdateClient failed due to JsonSyntaxException", e);
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Could not update client. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Could not update client. The server encountered a JSON syntax exception. Contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.error("apiUpdateClient failed due to IllegalStateException", e);
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Could not update client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Could not update client. The server encountered an IllegalStateException. Refresh and try again - if the problem persists, contact a system administrator for assistance.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -252,8 +264,8 @@ public class ClientAPI {
|
|||
|
||||
if (oldClient == null) {
|
||||
logger.error("apiUpdateClient failed; client with id " + id + " could not be found.");
|
||||
m.addAttribute("code", HttpStatus.NOT_FOUND);
|
||||
m.addAttribute("errorMessage", "Could not update client. The requested client with id " + id + "could not be found.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Could not update client. The requested client with id " + id + "could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -282,8 +294,8 @@ public class ClientAPI {
|
|||
|
||||
if (Strings.isNullOrEmpty(client.getJwksUri())) {
|
||||
logger.error("tried to create client with private key auth but no private key");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Can not create a client with private key authentication without registering a key via the JWS Set URI.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -293,15 +305,15 @@ public class ClientAPI {
|
|||
} else {
|
||||
|
||||
logger.error("unknown auth method");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute("errorMessage", "Unknown auth method requested");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Unknown auth method requested");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
|
||||
|
||||
}
|
||||
|
||||
ClientDetailsEntity newClient = clientService.updateClient(oldClient, client);
|
||||
m.addAttribute("entity", newClient);
|
||||
m.addAttribute(JsonEntityView.ENTITY, newClient);
|
||||
|
||||
if (AuthenticationUtilities.isAdmin(auth)) {
|
||||
return ClientEntityViewForAdmins.VIEWNAME;
|
||||
|
@ -324,11 +336,11 @@ public class ClientAPI {
|
|||
|
||||
if (client == null) {
|
||||
logger.error("apiDeleteClient failed; client with id " + id + " could not be found.");
|
||||
modelAndView.getModelMap().put("code", HttpStatus.NOT_FOUND);
|
||||
modelAndView.getModelMap().put("errorMessage", "Could not delete client. The requested client with id " + id + "could not be found.");
|
||||
modelAndView.getModelMap().put(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
modelAndView.getModelMap().put(JsonErrorView.ERROR_MESSAGE, "Could not delete client. The requested client with id " + id + "could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
modelAndView.getModelMap().put("code", HttpStatus.OK);
|
||||
modelAndView.getModelMap().put(HttpCodeView.CODE, HttpStatus.OK);
|
||||
clientService.deleteClient(client);
|
||||
}
|
||||
|
||||
|
@ -342,19 +354,19 @@ public class ClientAPI {
|
|||
* @param modelAndView
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value="/{id}", method=RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String apiShowClient(@PathVariable("id") Long id, Model model, Authentication auth) {
|
||||
|
||||
ClientDetailsEntity client = clientService.getClientById(id);
|
||||
|
||||
if (client == null) {
|
||||
logger.error("apiShowClient failed; client with id " + id + " could not be found.");
|
||||
model.addAttribute("code", HttpStatus.NOT_FOUND);
|
||||
model.addAttribute("errorMessage", "The requested client with id " + id + " could not be found.");
|
||||
model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
model.addAttribute(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + id + " could not be found.");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
model.addAttribute("entity", client);
|
||||
model.addAttribute(JsonEntityView.ENTITY, client);
|
||||
|
||||
if (AuthenticationUtilities.isAdmin(auth)) {
|
||||
return ClientEntityViewForAdmins.VIEWNAME;
|
||||
|
@ -362,4 +374,10 @@ public class ClientAPI {
|
|||
return ClientEntityViewForUsers.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,14 @@ import org.mitre.openid.connect.service.impl.MITREidDataService_1_1;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
|
@ -49,10 +54,12 @@ import com.google.gson.stream.JsonWriter;
|
|||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/api/data")
|
||||
@RequestMapping("/" + DataAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')") // you need to be an admin to even think about this -- this is a potentially dangerous API!!
|
||||
public class DataAPI {
|
||||
|
||||
public static final String URL = RootController.API_URL + "/data";
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -72,7 +79,10 @@ public class DataAPI {
|
|||
@Autowired
|
||||
private MITREidDataService_1_1 dataService_1_2;
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json")
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String importData(Reader in, Model m) throws IOException {
|
||||
|
||||
JsonReader reader = new JsonReader(in);
|
||||
|
@ -107,10 +117,10 @@ public class DataAPI {
|
|||
return "httpCodeView";
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public void exportData(HttpServletResponse resp, Principal prin) throws IOException {
|
||||
|
||||
resp.setContentType("application/json");
|
||||
resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
|
||||
// this writer puts things out onto the wire
|
||||
JsonWriter writer = new JsonWriter(resp.getWriter());
|
||||
|
@ -140,5 +150,10 @@ public class DataAPI {
|
|||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
|
||||
}
|
|
@ -44,11 +44,16 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
|
||||
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -61,9 +66,11 @@ import com.google.common.collect.Sets;
|
|||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "register")
|
||||
@RequestMapping(value = DynamicClientRegistrationEndpoint.URL)
|
||||
public class DynamicClientRegistrationEndpoint {
|
||||
|
||||
public static final String URL = "register";
|
||||
|
||||
@Autowired
|
||||
private ClientDetailsEntityService clientService;
|
||||
|
||||
|
@ -85,6 +92,9 @@ public class DynamicClientRegistrationEndpoint {
|
|||
@Autowired
|
||||
private OIDCTokenService connectTokenService;
|
||||
|
||||
@Autowired
|
||||
private WebResponseExceptionTranslator providerExceptionHandler;
|
||||
|
||||
/**
|
||||
* Logger for this class
|
||||
*/
|
||||
|
@ -97,7 +107,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
* @param p
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
||||
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String registerNewClient(@RequestBody String jsonString, Model m) {
|
||||
|
||||
ClientDetailsEntity newClient = null;
|
||||
|
@ -107,7 +117,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
// bad parse
|
||||
// didn't parse, this is a bad request
|
||||
logger.error("registerNewClient failed; submitted JSON is malformed");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -131,9 +141,9 @@ public class DynamicClientRegistrationEndpoint {
|
|||
newClient = validateAuth(newClient);
|
||||
} catch (ValidationException ve) {
|
||||
// validation failed, return an error
|
||||
m.addAttribute("error", ve.getError());
|
||||
m.addAttribute("errorMessage", ve.getErrorDescription());
|
||||
m.addAttribute("code", ve.getStatus());
|
||||
m.addAttribute(JsonErrorView.ERROR, ve.getError());
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, ve.getErrorDescription());
|
||||
m.addAttribute(HttpCodeView.CODE, ve.getStatus());
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -172,26 +182,26 @@ public class DynamicClientRegistrationEndpoint {
|
|||
|
||||
RegisteredClient registered = new RegisteredClient(savedClient, token.getValue(), config.getIssuer() + "register/" + UriUtils.encodePathSegment(savedClient.getClientId(), "UTF-8"));
|
||||
m.addAttribute("client", registered);
|
||||
m.addAttribute("code", HttpStatus.CREATED); // http 201
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.CREATED); // http 201
|
||||
|
||||
return ClientInformationResponseView.VIEWNAME;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Unsupported encoding", e);
|
||||
m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Couldn't save client", e);
|
||||
|
||||
m.addAttribute("error", "invalid_client_metadata");
|
||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||
m.addAttribute(JsonErrorView.ERROR, "invalid_client_metadata");
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Unable to save client due to invalid or inconsistent metadata.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400
|
||||
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
} else {
|
||||
// didn't parse, this is a bad request
|
||||
logger.error("registerNewClient failed; submitted JSON is malformed");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400
|
||||
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
@ -206,7 +216,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + SystemScopeService.REGISTRATION_TOKEN_SCOPE + "')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String readClientConfiguration(@PathVariable("id") String clientId, Model m, OAuth2Authentication auth) {
|
||||
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
|
@ -219,12 +229,12 @@ public class DynamicClientRegistrationEndpoint {
|
|||
|
||||
// send it all out to the view
|
||||
m.addAttribute("client", registered);
|
||||
m.addAttribute("code", HttpStatus.OK); // http 200
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.OK); // http 200
|
||||
|
||||
return ClientInformationResponseView.VIEWNAME;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Unsupported encoding", e);
|
||||
m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -232,7 +242,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
// client mismatch
|
||||
logger.error("readClientConfiguration failed, client ID mismatch: "
|
||||
+ clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match.");
|
||||
m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403
|
||||
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
@ -247,7 +257,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + SystemScopeService.REGISTRATION_TOKEN_SCOPE + "')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String updateClient(@PathVariable("id") String clientId, @RequestBody String jsonString, Model m, OAuth2Authentication auth) {
|
||||
|
||||
|
||||
|
@ -258,7 +268,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
// bad parse
|
||||
// didn't parse, this is a bad request
|
||||
logger.error("updateClient failed; submitted JSON is malformed");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId);
|
||||
|
@ -291,9 +301,9 @@ public class DynamicClientRegistrationEndpoint {
|
|||
newClient = validateAuth(newClient);
|
||||
} catch (ValidationException ve) {
|
||||
// validation failed, return an error
|
||||
m.addAttribute("error", ve.getError());
|
||||
m.addAttribute("errorMessage", ve.getErrorDescription());
|
||||
m.addAttribute("code", ve.getStatus());
|
||||
m.addAttribute(JsonErrorView.ERROR, ve.getError());
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, ve.getErrorDescription());
|
||||
m.addAttribute(HttpCodeView.CODE, ve.getStatus());
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
@ -307,19 +317,19 @@ public class DynamicClientRegistrationEndpoint {
|
|||
|
||||
// send it all out to the view
|
||||
m.addAttribute("client", registered);
|
||||
m.addAttribute("code", HttpStatus.OK); // http 200
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.OK); // http 200
|
||||
|
||||
return ClientInformationResponseView.VIEWNAME;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("Unsupported encoding", e);
|
||||
m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Couldn't save client", e);
|
||||
|
||||
m.addAttribute("error", "invalid_client_metadata");
|
||||
m.addAttribute("errorMessage", "Unable to save client due to invalid or inconsistent metadata.");
|
||||
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
|
||||
m.addAttribute(JsonErrorView.ERROR, "invalid_client_metadata");
|
||||
m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Unable to save client due to invalid or inconsistent metadata.");
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400
|
||||
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
@ -327,7 +337,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
// client mismatch
|
||||
logger.error("updateClient failed, client ID mismatch: "
|
||||
+ clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match.");
|
||||
m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403
|
||||
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
@ -341,7 +351,7 @@ public class DynamicClientRegistrationEndpoint {
|
|||
* @return
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + SystemScopeService.REGISTRATION_TOKEN_SCOPE + "')")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "application/json")
|
||||
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String deleteClient(@PathVariable("id") String clientId, Model m, OAuth2Authentication auth) {
|
||||
|
||||
ClientDetailsEntity client = clientService.loadClientByClientId(clientId);
|
||||
|
@ -350,14 +360,14 @@ public class DynamicClientRegistrationEndpoint {
|
|||
|
||||
clientService.deleteClient(client);
|
||||
|
||||
m.addAttribute("code", HttpStatus.NO_CONTENT); // http 204
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT); // http 204
|
||||
|
||||
return HttpCodeView.VIEWNAME;
|
||||
} else {
|
||||
// client mismatch
|
||||
logger.error("readClientConfiguration failed, client ID mismatch: "
|
||||
+ clientId + " and " + auth.getOAuth2Request().getClientId() + " do not match.");
|
||||
m.addAttribute("code", HttpStatus.FORBIDDEN); // http 403
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403
|
||||
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
@ -559,4 +569,10 @@ public class DynamicClientRegistrationEndpoint {
|
|||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(OAuth2Exception.class)
|
||||
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
|
||||
logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
|
||||
return providerExceptionHandler.translate(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
|||
import org.mitre.jwt.signer.service.JWTSigningAndValidationService;
|
||||
import org.mitre.openid.connect.view.JWKSetView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -30,10 +31,12 @@ import com.nimbusds.jose.jwk.JWK;
|
|||
@Controller
|
||||
public class JWKSetPublishingEndpoint {
|
||||
|
||||
public static final String URL = "jwk";
|
||||
|
||||
@Autowired
|
||||
private JWTSigningAndValidationService jwtService;
|
||||
|
||||
@RequestMapping(value = "/jwk", produces = "application/json")
|
||||
@RequestMapping(value = "/" + URL, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getJwk(Model m) {
|
||||
|
||||
// map from key id to key
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue