I tried to make an oauth server with separate resource server but I can't have a connection between them.
OAuth2Config:
#Configuration
#EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter
{
#Autowired
#Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private ResourceLoader resourceLoader;
#Value("${logistics.oauth.tokenTimeout:36000}")
private int expiration;
#Value("${security.jwt.resource-ids}")
private String resourceIds;
#Value("${server.ssl.key-store}")
private String keystore;
#Value("${server.ssl.key-store-password}")
private String password;
#Value("${server.ssl.key-alias}")
private String alias;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer configurer) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
configurer.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("logistics").secret(passwordEncoder().encode("secret")).accessTokenValiditySeconds(expiration)
.scopes("read", "write").authorizedGrantTypes("password", "refresh_token","authorization_code").resourceIds(resourceIds);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Bean
#Primary
public DefaultTokenServices tokenServices(){
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setTokenEnhancer(accessTokenConverter());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
#Bean
public TokenStore tokenStore() {return new JwtTokenStore(accessTokenConverter());}
#Bean
public JwtAccessTokenConverter accessTokenConverter(){
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
Resource resource = resourceLoader.getResource(keystore);
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,password.toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair(alias));
return converter;
}
#Bean
public TokenEnhancer tokenEnhancer(){return new CustomTokenEnhancer();}
}
WebsecurityConfig OAut2Server:
#Configuration
#EnableWebMvc
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
#Autowired
private UserDetailsService userDetailsService;
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests().antMatchers("/login").permitAll()
.antMatchers("/oauth/token/revokeById/**").permitAll()
.antMatchers("/tokens/**").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
// #formatter:on
}
#Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
application.properties:
server.port=81
server.ssl.key-alias=alias
server.ssl.key-store-type=jks
server.ssl.key-store-password=password
server.ssl.key-password=password
server.ssl.key-store=classpath:keystore.jks
server.ssl.enabled=true
server.ssl.ciphers=TLS_RSA_WITH_AES_128_CBC_SHA256,
INCLUDE_ANY_OTHER_ONES_YOU_NEED_TO_SUPPORT
server.ssl.protocol=TLS
server.ssl.enabled-protocols=TLSv1.2
I don't know what I'm doing wrong. I've followed multiple tutorials but none of them worked. Can someone see what I'm doing wrong?
Related
I am trying to have a custom authentication provider where I would like to have a keycloak as an authenticator.
Have created just a simple class for authentication provider but its not being called.
#Component
public class CustomKeycloakAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(Authentication auth)
throws AuthenticationException {
String username = auth.getName();
String password = auth.getCredentials()
.toString();
if ("externaluser".equals(username) && "pass".equals(password)) {
return new UsernamePasswordAuthenticationToken
(username, password, Collections.emptyList());
} else {
throw new
BadCredentialsException("External system authentication failed");
}
}
#Override
public boolean supports(Class<?> auth) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(auth));
}
}
Here is my WebConfig class:
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
//#EnableMyHttpSession
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientDetailsService;
private AccessDecisionManager accessDecisionManager;
#Autowired
private CustomKeycloakAuthenticationProvider keycloakAuthenticationProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().accessDecisionManager(accessDecisionManager)
// .antMatchers("/oauth/token", "/*.html", "/js/**", "/images/**",
// "/styles/**").permitAll().
.antMatchers("/service/*").fullyAuthenticated()
// .antMatchers("/reports/*").fullyAuthenticated()
.anyRequest().permitAll().and().httpBasic().and().csrf().disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(keycloakAuthenticationProvider);
}
#Override
#Bean(name = "authenticationManagerBean")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
#Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
#Bean
#Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
#Bean
public AffirmativeBased accessDecisionManager() {
List<AccessDecisionVoter<?>> accessDecisionVoters = new ArrayList<>();
accessDecisionVoters.add(new ScopeVoter());
accessDecisionVoters.add(new RoleVoter());
accessDecisionVoters.add(new AuthenticatedVoter());
AffirmativeBased accessDecisionManager = new AffirmativeBased(accessDecisionVoters);
return accessDecisionManager;
}
I also have a Authorization Server:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(AuthorizationServerConfiguration.class);
//private static String REALM="MY_OAUTH_REALM";
#Autowired
private DataSource dateSource;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private CustomClientBuilder customClientBuilder;
#Autowired
private TokenStore tokenStore;
#Autowired
public UserService userService;
#Autowired
private CustomClientService customClientService;
#Autowired
private AccessRightsService accessRightService;
private MyTokenServices tokenServices = null;
#Bean
#Primary
public MyTokenServices tokenServices() {
if(tokenServices != null) return tokenServices;
tokenServices = new MyTokenServices();
tokenServices.setTokenStore(tokenStore);
tokenServices.setClientDetailsService(customClientService);
tokenServices.setAuthenticationManager(authenticationManager);
tokenServices.userService = userService;
tokenServices.accessRightService = accessRightService;
return tokenServices;
}
#Bean
#Primary
public TokenStore tokenStore( #Value("${oauth2Token.store.type}") String tokenStoreType) {
TokenStore tokenStore = null;
log.info("Token store is type " + tokenStoreType);
if(tokenStoreType.toLowerCase().equals("jdbc")){
tokenStore = new JdbcTokenStore(dateSource);
}else {
tokenStore = new InMemoryTokenStore();
}
log.info("Token store is " + tokenStore);
return tokenStore;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.setBuilder(customClientBuilder);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.tokenServices(tokenServices())
.userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager).addInterceptor(new HandlerInterceptorAdapter() {
#Override
public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o) throws Exception {
rs.setHeader("Access-Control-Allow-Origin", "*");
rs.setHeader("Access-Control-Allow-Methods", "*");
rs.setHeader("Access-Control-Max-Age", "3600");
rs.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
log.info(hsr.getMethod());
if(hsr.getMethod().equals("OPTIONS")){
rs.setStatus(200); // hard fix for options
}
return true;
}
});
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients();
}
When I try to do a login in the providers there are only 2 of them:
I have tried to put #Autowired to protected void configure(AuthenticationManagerBuilder auth) { but it didn't helped
Don't know if there is something in configuration that I am missing so it doesn't add the 3rd authentication provider.
With Spring Security keyclaock can be configured with a class that derive of KeycloakWebSecurityConfigurerAdapter
#Configuration
#EnableWebSecurity
#KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
(https://www.keycloak.org/docs/latest/securing_apps/)
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>20.0.2</version>
</dependency>
I think you don't need to create your own AuthenticationProvider keycloak give you an implementation KeycloakAuthenticationProvider
Update OK (but why ?) :
So I think you don't need to override that method
#Override
protected void configure(AuthenticationManagerBuilder auth)
Create another one like this
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(keycloakAuthenticationProvider());
}
I'm using Spring 2.3.12.RELEASE with Hoxton.SR11 as cloud version. The dependency I'm using is spring-cloud-starter-oauth2.
I just configure all the oauth server but when I'm trying to do login I get a 401 response. I think that I'm missing something but I cannot fix it.
Here is the code:
AuthoritationServerConfig
#RefreshScope
#Configuration
#EnableAuthorizationServer
public class AuthoritationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#Autowired
private AuthenticationManager authenticacionManager;
#Autowired
private InfoAdicionalToken infoAdicionalToken;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient(env.getProperty("config.security.oauth.client.id"))
.secret(passwordEncoder.encode(env.getProperty("config.security.oauth.client.secret")))
.scopes("read", "write").authorizedGrantTypes("password", "refresh_token")
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(3600);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(infoAdicionalToken, accessTokenConverter()));
endpoints.authenticationManager(this.authenticacionManager)
.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter()).tokenEnhancer(tokenEnhancerChain);
}
#Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
tokenConverter.setSigningKey(env.getProperty("config.security.oauth.jwt.key"));
return tokenConverter;
}
}
SpringSecurityConfig
#Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService usuarioService;
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
#Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.usuarioService).passwordEncoder(passwordEncoder());
}
#Override
#Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
ResourceServerConfig
#RefreshScope
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Value("${config.security.oauth.jwt.key}")
private String jwtKey;
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/api/security/oauth/**").permitAll();
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(tokenStore());
}
#Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
tokenConverter.setSigningKey(jwtKey);
return tokenConverter;
}
Zuul application properties
zuul.routes.security.service-id=servicio-oauth
zuul.routes.security.path=/api/security/**
zuul.routes.security.sensitive-headers=Cookie,Set-Cookie
This is a capture of the request:
Request headers:
Response headers:
Thank you in advance.
I'm having a problem configuring an Oauth2 Auth Server in Spring, I have my custom AuthenticationProvider and I'm defining my own AuthenticationManager, but everytime that I do a request for a token to "/oauth/token", I see that Spring keeps injecting and calling the default DaoAuthenticationProvider in the ProviderManager defined by Spring.
This are my configuration classes:
#Configuration
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private AuthenticationManager authenticationManager;
public AuthorizationServerConfiguration(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
#Bean
PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Bean
JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
return converter;
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private AuthenticationProvider authenticationProvider;
public WebSecurityConfig(AuthenticationProvider authenticationProvider) {
this.authenticationProvider = authenticationProvider;
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(authenticationProvider);
}
}
Thanks in advance
EDIT
#Service
public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private ADCustomerService adCustomerService;
public CustomAuthenticationProvider(ADCustomerService adCustomerService) {
this.adCustomerService = adCustomerService;
}
#Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
}
#Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
return adCustomerService.retrieveUser(username, authentication);
}
}
You need to override configure(AuthenticationManagerBuilder auth) from WebSecurityConfigurerAdapter class
The final class should look something like this
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider authenticationProvider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
}
Edit your WebSecurityConfig as follows:
FROM
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private AuthenticationProvider authenticationProvider;
public WebSecurityConfig(AuthenticationProvider authenticationProvider) {
this.authenticationProvider = authenticationProvider;
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(authenticationProvider);
}
}
TO
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private CustomAuthenticationProvider customAuthenticationProvider;
public WebSecurityConfig(AuthenticationProvider authenticationProvider) {
this.authenticationProvider = authenticationProvider;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return new ProviderManager(authenticationProvider);
}
}
I'm following this article and my application is also the same pattern. But I need multiple Login URL like
/loginUrl1
/loginUrl2
/loginUrl3
instead of single currently URL is /oauth/token
Here's also my similar AuthorizationServer
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
static final String CLIEN_ID = "devglan-client";
static final String CLIENT_SECRET = "devglan-secret";
static final String GRANT_TYPE = "password";
static final String AUTHORIZATION_CODE = "authorization_code";
static final String REFRESH_TOKEN = "refresh_token";
static final String IMPLICIT = "implicit";
static final String SCOPE_READ = "read";
static final String SCOPE_WRITE = "write";
static final String TRUST = "trust";
static final int ACCESS_TOKEN_VALIDITY_SECONDS = 1*60*60;
static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 6*60*60;
#Autowired
private TokenStore tokenStore;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(CLIEN_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
}
ResourceServerConfig
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.
anonymous().disable()
.authorizeRequests()
.antMatchers("/users/**").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
Here's my SecurityConfig.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Resource(name = "userService")
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/api-docs/**").permitAll();
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Bean
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
I am trying to implement Oauth2 with spring boot with the configurations as below
Securty configuration:
#Configuration
#EnableWebSecurity(debug = true)
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
auth.userDetailsService(userDetailsService);
}
public AuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
return daoAuthenticationProvider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().anonymous().disable().authorizeRequests()
.antMatchers("/oauth2/login","/logout").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/oauth2/login").loginProcessingUrl("/login").permitAll();
}
}
Authorization configuration
#Configuration
#EnableAuthorizationServer
public class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private TokenStore tokenStore;
#Autowired
private ClientDetailsService clientDetailsService;
#Bean
public TokenStore tokenStore(DataSource dataSource){
return new JdbcTokenStore(dataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer()));
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore)
.tokenEnhancer(enhancerChain)
.tokenGranter(new CompositeTokenGranter(getCustomizedTokenGranters()))
.tokenServices(tokenServices())
.approvalStoreDisabled();
}
#Bean
#Primary
public AuthorizationServerTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenEnhancer(tokenEnhancer());
tokenServices.setTokenStore(tokenStore);
tokenServices.setClientDetailsService(clientDetailsService);
return tokenServices;
}
#Bean
public TokenEnhancer tokenEnhancer(){
return (accessToken, authentication) -> {
if(!"client_credentials".equalsIgnoreCase(authentication.getOAuth2Request().getRequestParameters().get(OAuth2Utils.GRANT_TYPE)))
{
ExtendedUser principal = (ExtendedUser) authentication.getPrincipal();
Map<String, Object> additionalInfo = Maps.newHashMap();
additionalInfo.put("user_id", principal.getUserId());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
}
return accessToken;
};
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("permitAll()")
.tokenKeyAccess("permitAll()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
#Bean
public ClientDetailsService clientDetailsService(DataSource dataSource){
return new CachedClientDetailsService(dataSource);
}
private List<TokenGranter> getCustomizedTokenGranters() {
AuthorizationServerTokenServices tokenServices = tokenServices();
ClientDetailsService clientDetails = clientDetailsService;
OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetails);
RefreshTokenGranter refreshTokenGranter = new RefreshTokenGranter(tokenServices, clientDetails, requestFactory);
ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory);
ClientCredentialsTokenGranter clientCredentialsTokenGranter = new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory);
clientCredentialsTokenGranter.setAllowRefresh(true);//custom config, see AuthorizationServerEndpointsConfigurer.getDefaultTokenGranters
List<TokenGranter> tokenGranters = Lists.newArrayList();
tokenGranters.add(refreshTokenGranter);
tokenGranters.add(implicit);
tokenGranters.add(clientCredentialsTokenGranter);
if (authenticationManager != null) {
tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory));
}
return tokenGranters;
}
}
Resource server configuration :
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/**").authenticated();
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("identity-service");
}
#Bean
public ResourceServerTokenServices resourceServerTokenServices(TokenStore tokenStore){
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
return tokenServices;
}
}
application.properties
security.oauth2.resource.filter-order = 3
the resource server is on the same authorization server (Same Application), and I am trying to implement the Implicit grant (Password grant working just fine)
when I am trying to login in to complete the implicit grant (oauth/authorize endpoint need authentication) I am getting /login 404 ?
spring boot: 1.5.10,
spring security Oauth2: 2.0.14
Finally, i managed to make it work
Security Configuration :
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/**").and().csrf().disable().authorizeRequests()
.antMatchers("/oauth2/login","/logout").permitAll()
.antMatchers("/oauth/authorize").authenticated()
.and().formLogin().loginPage("/oauth2/login").loginProcessingUrl("/login").permitAll();
}
Resources Server Configuration
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/api/**").and().anonymous().disable().authorizeRequests()
.anyRequest().authenticated();
}
I had to enable the anonymous in spring security and specify mapping URI matcher for both spring security and resource server
Resource server on /api/**
,Spring security on /**
and for taking care of the ordering (on version 1.5.10)
application.properties
security.oauth2.resource.filter-order = 3