Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
java-spring-oidc-example
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
demo
java-spring-oidc-example
Commits
a4b8e548
Commit
a4b8e548
authored
Oct 10, 2018
by
Jasha Joachimsthal
Committed by
陈健
Sep 17, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
OAUTH-3116 Use nimbus library for the JWT
parent
f310ee31
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
35 additions
and
44 deletions
+35
-44
README.md
README.md
+1
-1
pom.xml
pom.xml
+4
-4
Application.java
...main/java/com/github/fromi/openidconnect/Application.java
+2
-2
OpenIDConnectAuthenticationFilter.java
...idconnect/security/OpenIDConnectAuthenticationFilter.java
+26
-35
application.yml
src/main/resources/application.yml
+2
-2
No files found.
README.md
View file @
a4b8e548
...
...
@@ -38,7 +38,7 @@ ___Example configuration___
oauth2:
clientId: openid-client
clientSecret: secret
issuer: http://localhost:7878/oauth
/
issuer: http://localhost:7878/oauth
## Run and test
Run the example via the Run configuration in IntelliJ or via the command line:
`mvn spring-boot:run`
. The Token Server needs to be accessible to start this
...
...
pom.xml
View file @
a4b8e548
...
...
@@ -5,7 +5,7 @@
<modelVersion>
4.0.0
</modelVersion>
<groupId>
com.onegini.oidc
</groupId>
<artifactId>
spring-google-openidconnect
</artifactId>
<artifactId>
java-spring-oidc-example
</artifactId>
<version>
1.0.0-SNAPSHOT
</version>
<packaging>
war
</packaging>
...
...
@@ -34,9 +34,9 @@
</dependency>
<dependency>
<groupId>
com.
auth0
</groupId>
<artifactId>
jwks-rsa
</artifactId>
<version>
0.3.0
</version>
<groupId>
com.
nimbusds
</groupId>
<artifactId>
oauth2-oidc-sdk
</artifactId>
<version>
5.63
</version>
</dependency>
<dependency>
...
...
src/main/java/com/github/fromi/openidconnect/Application.java
View file @
a4b8e548
...
...
@@ -11,12 +11,12 @@ import org.springframework.context.annotation.ScopedProxyMode;
@EnableAutoConfiguration
public
class
Application
extends
SpringBootServletInitializer
{
public
static
void
main
(
String
[]
args
)
{
public
static
void
main
(
final
String
[]
args
)
{
SpringApplication
.
run
(
Application
.
class
);
}
@Override
protected
SpringApplicationBuilder
configure
(
SpringApplicationBuilder
application
)
{
protected
SpringApplicationBuilder
configure
(
final
SpringApplicationBuilder
application
)
{
return
application
.
sources
(
Application
.
class
);
}
...
...
src/main/java/com/github/fromi/openidconnect/security/OpenIDConnectAuthenticationFilter.java
View file @
a4b8e548
...
...
@@ -3,9 +3,7 @@ package com.github.fromi.openidconnect.security;
import
static
java
.
util
.
Optional
.
empty
;
import
static
org
.
springframework
.
security
.
core
.
authority
.
AuthorityUtils
.
NO_AUTHORITIES
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.security.interfaces.RSAPublicKey
;
import
java.text.ParseException
;
import
java.util.Date
;
import
java.util.Map
;
import
java.util.Objects
;
...
...
@@ -16,25 +14,19 @@ import javax.servlet.http.HttpServletResponse;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.authentication.BadCredentialsException
;
import
org.springframework.security.authentication.CredentialsExpiredException
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.jwt.Jwt
;
import
org.springframework.security.jwt.JwtHelper
;
import
org.springframework.security.jwt.crypto.sign.RsaVerifier
;
import
org.springframework.security.oauth2.client.OAuth2RestOperations
;
import
org.springframework.security.oauth2.client.discovery.ProviderConfiguration
;
import
org.springframework.security.oauth2.client.http.AccessTokenRequiredException
;
import
org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails
;
import
org.springframework.security.oauth2.common.OAuth2AccessToken
;
import
org.springframework.security.oauth2.common.exceptions.InvalidTokenException
;
import
org.springframework.security.oauth2.common.exceptions.OAuth2Exception
;
import
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
;
import
org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
;
import
com.auth0.jwk.Jwk
;
import
com.auth0.jwk.JwkException
;
import
com.auth0.jwk.JwkProvider
;
import
com.auth0.jwk.UrlJwkProvider
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.nimbusds.jwt.JWT
;
import
com.nimbusds.jwt.JWTClaimsSet
;
import
com.nimbusds.jwt.JWTParser
;
public
class
OpenIDConnectAuthenticationFilter
extends
AbstractAuthenticationProcessingFilter
{
...
...
@@ -59,7 +51,7 @@ public class OpenIDConnectAuthenticationFilter extends AbstractAuthenticationPro
}
@Override
public
Authentication
attemptAuthentication
(
final
HttpServletRequest
request
,
final
HttpServletResponse
response
)
throws
IOException
{
public
Authentication
attemptAuthentication
(
final
HttpServletRequest
request
,
final
HttpServletResponse
response
)
{
//Use ID token to retrieve user info -> when we do this we also verify the ID token
final
OAuth2AccessToken
accessToken
;
...
...
@@ -71,20 +63,22 @@ public class OpenIDConnectAuthenticationFilter extends AbstractAuthenticationPro
}
// Option 1: Use claim to create UserInfo
try
{
final
String
idToken
=
accessToken
.
getAdditionalInformation
().
get
(
"id_token"
).
toString
();
final
String
kid
=
JwtHelper
.
headers
(
idToken
).
get
(
"kid"
);
final
Jwt
tokenDecoded
=
JwtHelper
.
decodeAndVerify
(
idToken
,
verifier
(
kid
));
final
Map
<
String
,
String
>
authInfo
=
new
ObjectMapper
().
readValue
(
tokenDecoded
.
getClaims
(),
Map
.
class
);
verifyClaims
(
authInfo
);
try
{
final
JWT
jwt
=
JWTParser
.
parse
(
idToken
);
// TODO OAUTH-3116: validate the JWT
final
JWTClaimsSet
jwtClaimsSet
=
jwt
.
getJWTClaimsSet
();
final
Map
<
String
,
Object
>
authInfo
=
jwtClaimsSet
.
getClaims
();
// TODO OAUTH-3116: find a way to make them available in the modelMap
verifyClaims
(
jwtClaimsSet
);
final
UserInfo
user
=
new
UserInfo
().
setId
(
authInfo
.
get
(
"sub"
)).
setName
(
authInfo
.
get
(
"sub"
));
final
UserInfo
user
=
new
UserInfo
().
setId
(
jwtClaimsSet
.
getSubject
()).
setName
(
jwtClaimsSet
.
getSubject
(
));
return
new
PreAuthenticatedAuthenticationToken
(
user
,
empty
(),
NO_AUTHORITIES
);
}
catch
(
final
InvalidToken
Exception
e
)
{
}
catch
(
final
Parse
Exception
e
)
{
throw
new
BadCredentialsException
(
"Could not obtain user details from token"
,
e
);
}
catch
(
final
JwkException
e
)
{
throw
new
AccessTokenRequiredException
(
e
.
getMessage
(),
details
);
}
// Option 2: Use UserInfo endpoint to retrieve user info
...
...
@@ -92,20 +86,17 @@ public class OpenIDConnectAuthenticationFilter extends AbstractAuthenticationPro
// return new PreAuthenticatedAuthenticationToken(userInfoResponseEntity.getBody(), empty(), NO_AUTHORITIES);
}
private
RsaVerifier
verifier
(
final
String
kid
)
throws
JwkException
{
final
JwkProvider
provider
=
new
UrlJwkProvider
(
providerConfiguration
.
getJwkSetUri
());
final
Jwk
jwk
=
provider
.
get
(
kid
);
return
new
RsaVerifier
((
RSAPublicKey
)
jwk
.
getPublicKey
());
private
void
verifyClaims
(
final
JWTClaimsSet
claims
)
{
final
Date
expireDate
=
claims
.
getExpirationTime
();
final
Date
now
=
new
Date
();
if
(
expireDate
.
before
(
now
))
{
throw
new
CredentialsExpiredException
(
"Claim has expired"
);
}
private
void
verifyClaims
(
final
Map
claims
)
{
final
int
exp
=
(
int
)
claims
.
get
(
"exp"
);
final
Date
expireDate
=
new
Date
(
exp
*
1000L
);
final
Date
now
=
new
Date
();
if
(
expireDate
.
before
(
now
)
||
!
Objects
.
equals
(
URI
.
create
(
issuer
).
getHost
(),
URI
.
create
((
String
)
claims
.
get
(
"iss"
)).
getHost
())
||
!
Objects
.
equals
(
clientId
,
claims
.
get
(
"aud"
)))
{
throw
new
RuntimeException
(
"Invalid claims"
);
if
(!(
Objects
.
equals
(
issuer
,
claims
.
getIssuer
())
&&
claims
.
getAudience
().
contains
(
clientId
)))
{
throw
new
BadCredentialsException
(
"Invalid claims"
);
}
}
...
...
src/main/resources/application.yml
View file @
a4b8e548
...
...
@@ -2,4 +2,4 @@ onegini:
oauth2
:
clientId
:
openid-client
clientSecret
:
secret
issuer
:
http://localhost:7878/oauth/
\ No newline at end of file
issuer
:
http://localhost:7878/oauth
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment