Comments (10)
After further experimentation with Spring Security 5.1 it turns out that with a valid JWT at hand, securing your resources in your Spring Boot application is as straight forward as:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/resources/**", "/error");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.mvcMatchers("/products/**").hasAuthority("MYROLE")
.and()
.oauth2ResourceServer()
.jwt()
.jwkSetUri("http://localhost:9011/.well-known/jwks.json")
.jwtAuthenticationConverter(grantedAuthoritiesExtractor())
// this disables session creation on Spring Security
//.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
;
}
private Converter<Jwt, AbstractAuthenticationToken> grantedAuthoritiesExtractor() {
return new JwtAuthenticationConverter() {
@Override
protected Collection<GrantedAuthority> extractAuthorities(Jwt jwt) {
Collection<String> authorities = (Collection<String>) jwt.getClaims().get("roles");
return authorities.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
};
}
}
from fusionauth-spring-security.
I upvoted this issue because i encountered the exact same problem. The filter given in this library is only useful for the Authorization Code grant, by analyzing the token in response of the redirectUri after a succesful login.
I made a custom TokenFilter that i register in the security chain, which check the validity of the token (with the public certificate), and then extract the informations needed in the JWT to create an authenticated user, with authorities extracted from the 'roles' key in the claims.
If i have time, i'll submit a PR of my work to help people, but for the moment the class is not generic at all and only fits to my specific needs...
from fusionauth-spring-security.
Does anyone have any news for us non-java devs on how this may be going? Is there a simple method for allowing our customers apps to authenticate with our APIs using client_credentials
?
from fusionauth-spring-security.
Hi @nikos thanks for the question.
FusionAuth does not currently support the client credentials grant, this will likely be coming this summer with a suite of IoT features.
We could look into adding the Password grant to this library, or if you'd like to submit a PR that would be great as well.
I'm not a Spring expert at all... so without digging back into the code your guess is as good as mine. If I have some cycles to take a look and see if I can stub it out I'll report back.
If you're looking to use the password or credentials grant, does this mean you'll be using it for something other than a normal web login workflow?
from fusionauth-spring-security.
Hi,
I recently heard that spring started including an OpenID Connect feature and I haven't had the time to look into it. When I get the chance I will update our example code to use the latest spring features.
from fusionauth-spring-security.
I recently heard that spring started including an OpenID Connect feature and I haven't had the time to look into it. When I get the chance I will update our example code to use the latest spring features.
Hi Typler, are you refering to the changes in Spring Security 5.1.x ?
https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Features-Matrix
Might be quite an impact worth a new branch since there seem many changes compared to Spring Security OAuth 2.x
from fusionauth-spring-security.
@damienherve my current approach is to make use of Spring's "standard" class when it comes to the password grants flow: org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails
and add userInfoUri for accessing OpenID metadata.
OpenIDResourceDetails
package io.fusionauth.patch.oauth;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
public interface OpenIDResourceDetails extends OAuth2ProtectedResourceDetails {
String getUserInfoUri();
void setUserInfoUri(String userInfoUri);
}
OpenIDPasswordResourceDetails
package io.fusionauth.patch.oauth;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
public class OpenIDPasswordResourceDetails extends ResourceOwnerPasswordResourceDetails implements OpenIDResourceDetails {
private String userInfoUri;
public String getUserInfoUri() {
return userInfoUri;
}
public void setUserInfoUri(String userInfoUri) {
this.userInfoUri = userInfoUri;
}
}
OpenIDConnectFilter
package io.fusionauth.patch.oauth;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.fusionauth.security.FusionAuthUserDetails;
// Patches io.fusionauth.security.OpenIDConnectFilter
public class OpenIDConnectFilter extends AbstractAuthenticationProcessingFilter {
private final OpenIDResourceDetails openIDResourceDetails;
private final OAuth2RestOperations restTemplate;
public OpenIDConnectFilter(String defaultFilterProcessesUrl, OpenIDResourceDetails openIDResourceDetails, OAuth2RestOperations restTemplate) {
super(defaultFilterProcessesUrl);
this.openIDResourceDetails = openIDResourceDetails;
this.restTemplate = restTemplate;
setAuthenticationManager(new NoopAuthenticationManager());
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
OAuth2AccessToken accessToken;
try {
accessToken = restTemplate.getAccessToken();
} catch (final OAuth2Exception e) {
throw new BadCredentialsException("Could not obtain access token", e);
}
try {
FusionAuthUserDetails user = new FusionAuthUserDetails(getUserInfo(accessToken), accessToken);
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
} catch (Exception e) {
throw new BadCredentialsException("Failed to validate the token", e);
}
}
private JsonNode getUserInfo(OAuth2AccessToken accessToken) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken.getValue());
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<String> response = new RestTemplate().exchange(openIDResourceDetails.getUserInfoUri(), HttpMethod.GET, httpEntity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
return new ObjectMapper().readTree(response.getBody());
}
throw new BadCredentialsException("Failed to request user details from the UserInfo API. " +
"Status code [" + response.getStatusCodeValue() + "] Message [" + response.getBody() + "]");
}
private static class NoopAuthenticationManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
throw new UnsupportedOperationException("No authentication should be done with this AuthenticationManager");
}
}
}
from fusionauth-spring-security.
I started working on a new example, based on how its going I think this repo will be deprecated in favor of just using spring security 5.
https://github.com/FusionAuth/fusionauth-spring-security-example/tree/SpringSecurity5
from fusionauth-spring-security.
Any update to support client_credentials grant type? thank you
from fusionauth-spring-security.
FusionAuth does not currently support the client credentials grant.
See FusionAuth feature request and ensure to upvote it.
FusionAuth/fusionauth-issues#155
If you have a business requirement for this, hit the FusionAuth Contact form and we can provide you a quote with a timeline.
Thanks!
from fusionauth-spring-security.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fusionauth-spring-security.