OAuth2 + Spring Boot 2 - ResourceServer in ZuulGateway with Authorization Server - spring

I am trying OAuth 2 + JWT integration using Spring Boot 2 + Netflix OSS. On requesting access token, I am getting the below error in Zuul Gateway which acts as a Resource Server.
2019-05-04 14:41:29.157 DEBUG 23272 --- [nio-8765-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
Can someone help and tell me what am I missing in the code ?
Zuul Gateway + Resource Server
#Configuration
#EnableResourceServer
#Order(value = 0)
#EnableOAuth2Sso
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth/token/**").permitAll()
//.antMatchers("/login/**,/oauth/**").permitAll()
.antMatchers("/trips/**").hasAnyRole("CLIENT", "USER", "ANONYMOUS")
.and().csrf().disable()
.anonymous().disable();
}
}
application.yml
logging:
level:
org.springframework: DEBUG
server:
port: 8765
spring:
application:
name: gateway
# Map path to auth service
zuul:
routes:
trips:
path: /trips/**
url: http://localhost:1000/api/trips
rides:
path: /rides/**
url: http://localhost:1000/api/rides
mauth:
path: /oauth/**
url: http://localhost:1000/oauth
#OAuth Configurations
security:
oauth2:
client:
#access-token-uri: https://auth/login
#user-authorization-uri: /auth/oauth/authorize
accessTokenUri: http://localhost:1000/oauth/authorize
userAuthorizationUri: http://localhost:1000/oauth/token
client-id: sapepool
client-secret: sapepool
resource:
jwt:
key-uri: http://localhost:1000/oauth/token_key
#key-value:
Authorization Server
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
#Qualifier("customUserDetailsService")
private UserDetailsService userDetailsService;
/**
* Token store.
*
* #return the token store
*/
/*#Bean
public DatastoreTokenStore tokenStore() {
return new DatastoreTokenStore(datastoreDataSource);
}*/
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
#Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "password".toCharArray()).getKeyPair("jwt"));
converter.setSigningKey("123");
converter.setVerifierKey("123");
return converter;
}
/**
*
*/
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService)
.tokenStore(tokenStore())//.tokenServices(tokenServices())
.tokenEnhancer(jwtAccessTokenConverter())
.accessTokenConverter(jwtAccessTokenConverter())
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
}
/**
* Authorization server security Configuration.
*
* #param oauthServer
* the oauth server
* #throws Exception
* the exception
*/
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("sapepool")
.secret("{noop}sapepool")
//.secret("sapepool")
.authorizedGrantTypes("client_credentials", "password","refresh_token")
.authorities("ROLE_CLIENT", "ROLE_ANDROID_CLIENT", "ROLE_ANONYMOUS")
.scopes("read", "write", "trust")
.accessTokenValiditySeconds(5000)
.refreshTokenValiditySeconds(50000);
//.resourceIds("oauth2-resource") - isAutoApprove()
}
}
Authorization Server - Web Security Config
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
#Autowired
private UserDetailsService userDetailsService;
#Override
#Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/oauth/token/**").permitAll()
.anyRequest().permitAll()
//.antMatchers("*/oauth/**").permitAll()
//.antMatchers("/**").permitAll()
.and().csrf().disable();
//.anonymous().disable();
/*
* http.csrf().disable().exceptionHandling() //.authenticationEntryPoint( //
* (request, response, authException) ->
* response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
* .and().authorizeRequests().antMatchers("/**").authenticated().and().httpBasic
* ();
*/
}
#Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}

Related

Unauthorized error while passing access_token to the REST Call

I have obtained the access token using appropriate endpoint using okta. using the obtained access token i am trying to make a REST call by passing access token as Authorization Header type Bearer. but getting 401 unauthorized error with the following error message
"Full authentication is required to access this resource"
AuthorizationServerConfig.java
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
static final String CLIENT_SECRET = "fXMuUOUo31nNlbnnjn64019h3JP-s6VZEOV4VGW1";
static final String CLIENT_ID = "0oaz4m4njwGDMqXB1356";
#Autowired
private TokenStore tokenStore;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer.inMemory()
.withClient(CLIENT_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(new String[] { "password", "refresh_token", "authorization_code" })
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(3600);
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.accessTokenConverter(accessTokenConverter());
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("as466gf");
return converter;
}
/**
* Bean for Token Servers Primary is added as there are three token services in the classpath
*
* #return DefaultTokenServices Default Token Service
*/
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
ResourceServerConfig.java
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/authenticate/**").permitAll()
.antMatchers("/user/greet/**").permitAll()
.antMatchers("/user/getRefreshedTokens/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("ResourceId");
}
}
SecurityConfig.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* OAuth ignores the configuration below
*
* #See ResourceServerConfig to control Authorization
*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/authenticate/**").permitAll()
.antMatchers("/user/greet/**").permitAll()
.antMatchers("/user/getRefreshedTokens/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}

Full authentication is required to access in Oauth2 authorization server

I have configured Authorization server and there is jdbc token store like this:
#Configuration
#EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
#Bean
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource oauthDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
public JdbcClientDetailsService clientDetailsService() {
return new JdbcClientDetailsService(oauthDataSource());
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(oauthDataSource());
}
#Bean
public ApprovalStore approvalStore() {
return new JdbcApprovalStore(oauthDataSource());
}
#Bean
public AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(oauthDataSource());
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.approvalStore(approvalStore())
.authorizationCodeServices(authorizationCodeServices())
.tokenStore(tokenStore());
}
}
and the spring security is like this:
#EnableWebSecurity
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
#Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new JdbcUserDetails();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/webjars/**","/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
//.authorizeRequests()
//.antMatchers("/login**","/logout**").permitAll()
//.antMatchers("/**").authenticated()
//.and()
.formLogin()
.loginPage("/login")
//.loginProcessingUrl("/login")
//.usernameParameter("username")
//.passwordParameter("password")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and()
.userDetailsService(userDetailsServiceBean());
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceBean())
.passwordEncoder(passwordEncoder());
}
}
and the its application.yml is:
server.contextPath: /auth
spring:
datasource:
url: jdbc:oracle:thin:#192.168.192.129:1521:hamed
hikari:
connection-test-query: SELECT 1 FROM DUAL
minimum-idle: 1
maximum-pool-size: 5
driver-class-name: oracle.jdbc.OracleDriver
username: test
password: test
initialization-mode: always
jpa:
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.Oracle12cDialect
show-sql: true
logging:
level:
org.springframework.security: DEBUG
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
server:
port: 8081
#keystore:
# password: mySecretKey
It is started successfully.
And the client is:
#SpringBootApplication
#EnableOAuth2Sso
#RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {
#RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**").permitAll()
.anyRequest().authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
public static void main(String[] args) {
SpringApplication.run(SocialApplication.class, args);
}
}
and the application.yml of the client is:
server:
port: 8090
security:
oauth2:
client:
clientId: curl_client
clientSecret: reza
accessTokenUri: http://localhost:8081/auth/oauth/token
userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
resource:
userInfoUri: http://localhost:8081/auth/user
logging:
level:
org.springframework.security: DEBUG
It is necessary to mention that the data of oauth_client_details is:
INSERT INTO oauth_client_details(client_id,
resource_ids,
client_secret,
scope,
authorized_grant_types,
web_server_redirect_uri,
authorities,
access_token_validity,
refresh_token_validity,
additional_information,
autoapprove
) VALUES('curl_client',
'product_api',
'reza',
'read,write',
'client_credentials',
'http://127.0.0.1',
'ROLE_PRODUCT_ADMIN',
7200,
0,
NULL,
'true');
But when I request the http://localhost:8090/user the following exception is raised:
Full authentication is required to access this resourceunauthorized
Where is wrong?
/login** permit all will need to be above /** authorizeRequests. Let's try this:
#SpringBootApplication
#EnableOAuth2Sso
#RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {
#RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**").permitAll()
.antMatchers("/**").authenticated()
.and().logout().logoutSuccessUrl("/").permitAll().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
public static void main(String[] args) {
SpringApplication.run(SocialApplication.class, args);
}
}

Spring Boot OAuth2 "Full authentication is required to access this resource" after access-token retrieving

I am writing Spring Boot with OAuth2 application. My classes are:
AuthorizationServerConfig.class
<pre>
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends
AuthorizationServerConfigurerAdapter {
private static String REALM="CRM_REALM";
private static final int TEN_DAYS = 60 * 60 * 24 * 10;
private static final int ONE_DAY = 60 * 60 * 24;
private static final int THIRTY_DAYS = 60 * 60 * 24 * 30;
#Autowired
private DataSource dataSource;
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private CrmUserDetailsService crmUserDetailsService;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws
Exception {
// clients.jdbc(dataSource);
clients.inMemory()
.withClient("crmClient1")
.secret("crmSuperSecret")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
//.accessTokenValiditySeconds(ONE_DAY)
.accessTokenValiditySeconds(300)
.refreshTokenValiditySeconds(THIRTY_DAYS);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager)
.userDetailsService(crmUserDetailsService);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.realm(REALM);
}
}
</pre>
ResourceServerConfig.class
<pre>
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
//-- define URL patterns to enable OAuth2 security
http.
anonymous().disable()
.requestMatchers().antMatchers("/api/**")
.and().authorizeRequests()
.antMatchers("/api/**").access("hasRole('ADMIN') or hasRole('USER')")
.and().exceptionHandling().accessDeniedHandler(new
OAuth2AccessDeniedHandler());
}
}
</pre>
SecurityConfig.class
<pre>
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private CrmUserDetailsService crmUserDetailsService;
#Override
#Order(Ordered.HIGHEST_PRECEDENCE)
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers("/about").permitAll()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
//.antMatchers("/api/**").authenticated()
.anyRequest().authenticated()
.and()
.httpBasic()
.realmName("CRM_REALM");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(crmUserDetailsService)
.passwordEncoder(passwordEncoder());
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#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 PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
</pre>
SecurityWebApplicationInitializer.class
<pre>
public class SecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer {
}
</pre>
MethodSecurityConfig.class
<pre>
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration
{
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
</pre>
SignupService.class
<pre>
#Service
#Transactional
public class SignupService {
#Autowired
private UserRepository userRepository;
#Autowired
PasswordEncoder passwordEncoder;
public User addUser(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
/**
*
* set up a default customer with two roles USER and ADMIN
*
*/
#PostConstruct
private void setupDefaultUser() {
if (userRepository.count() == 0) {
userRepository.save(new User("crmadmin",
passwordEncoder.encode("adminpass"),
Arrays.asList(new UserRole("USER"), new
UserRole("ADMIN"))));
}
}
}
</pre>
After I send request localhost:8080/oauth/token and get access_token and refresh_token later when I try send api request with Authorization: Bearer (access_token) I got error:
<pre>
{
"timestamp": 1534343851414,
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/api/customers"
}
</pre>
Could you help me?

OAUTH2: On accessing the REST end point from customer end UI to secure URI returns anonymousUser

I am working on OAUTH2 spring security, i am supposed to hit http://localhost:8082/ui - REST end point from client UI which will take me to the secure URI http://localhost:8082/secure after logging into the auth server http://localhost:8081/auth/login.
But instead it after hitting on client UI http://localhost:8082/ui it is directly taking me to http://localhost:8082/secure, not prompting for login page. and on secure page "anonymousUser" value is returned.
I am sharing my client and server below, and value returned is "Welcome Login User!== anonymousUser".
Any help would be really appreciated where i'm doing wrong.
my client side configuration
#EnableOAuth2Sso
#Configuration
#EnableWebSecurity
public class OauthConfig extends WebSecurityConfigurerAdapter {
#Autowired
private OAuth2ClientContextFilter oauth2ClientContextFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**")
.permitAll()
.antMatchers("/", "/login/**")
.permitAll()
.anyRequest()
.authenticated().and()
.httpBasic().and().addFilterAfter(oauth2ClientContextFilter, SecurityContextPersistenceFilter.class);
}
#Bean
protected OAuth2RestTemplate OAuth2RestTemplate(
OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
return new OAuth2RestTemplate(resource, context);
}
}
application.yml
server:
port: 8082
servlet:
context-path: /ui
session:
cookieName: UISESSION
security:
oauth2:
client:
clientId: ClientId
clientSecret: secret
accessTokenUri: http://localhost:8081/auth/oauth/token
userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
scope: openid
resource:
userInfoUri: http://localhost:8081/auth/rest/hello/principal
preferTokenInfo: false
application.properties
spring.thymeleaf.cache= false
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
server.port= 8082
server.servlet.session.cookie.name=UISESSION
spring.thymeleaf.mode=LEGACYHTML5
management.endpoints.web.expose=*
server side authorization server
#Configuration
#EnableAuthorizationServer
public class AuthorisationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
// TODO Auto-generated method stub
//security.allowFormAuthenticationForClients();
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("ClientId")//.authorities("ROLE_ADMIN")
.secret("{noop}secret")
.authorizedGrantTypes("authorization_code").scopes("user_info").autoApprove(true);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// TODO Auto-generated method stub
endpoints.authenticationManager(authenticationManager);
}
}
serve side resource server
#EnableResourceServer
#Configuration
#Order(1000)
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserDetailsService customUserDetailsService;
#Autowired
public ResourceServerConfig(AuthenticationManager authenticationManager,
CustomUserDetailsService customUserDetailsService) {
this.authenticationManager = authenticationManager;
this.customUserDetailsService = customUserDetailsService;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers().antMatchers("/login","/oauth/authorize").and().authorizeRequests()
.anyRequest().authenticated().and().formLogin().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager).
userDetailsService(customUserDetailsService);
}
}
server side Service
#Service
public class CustomUserDetailsService implements UserDetailsService{
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
Optional<Users> userOptional= userRepository.findByName(username);
userOptional.orElseThrow(() -> new UsernameNotFoundException("user not found"));
return userOptional.map(users -> new CustomUserDetails(users)).get();
}
}

spring OAuth2 zuul--Access token expired,invalid_token

I have a spring zuul OAuth2 app.
authServer--
OAuth2ServerConfiguration:
#Configuration
public class {
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception { http .authorizeRequests()
.antMatchers( "/oauth/authorize/**","/oauth/check_token/**").permitAll()
.anyRequest().authenticated();
// #formatter:on
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
//private TokenStore tokenStore = new InMemoryTokenStore();
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
TokenStore tokenStore;
#Autowired
private CustomUserDetailService customUserDetailService;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
// #formatter:off
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(customUserDetailService);
// #formatter:on
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// #formatter:off
clients
.inMemory()
.withClient("kksdi2388wmkwe")
.authorizedGrantTypes("authorization_code","password", "refresh_token")
.scopes("read", "write")
.resourceIds("ReadAndWriteResource")
.secret("kksd23isdmsisdi2")
.autoApprove(true)
.accessTokenValiditySeconds(120)
.refreshTokenValiditySeconds(1200);
// #formatter:on
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
}
webSecurity:
#Configuration
#EnableWebSecurity
#Order(-20)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/login", "/").permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.csrf().disable()
.requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
.and()
.authorizeRequests().anyRequest().authenticated()
;
// #formatter:on
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);
}
}
zuul server:
security:
user:
password: none
oauth2:
client:
accessTokenUri: http://localhost:9999/uaa/oauth/token
userAuthorizationUri: http://localhost:9999/uaa/oauth/authorize
clientId: kksdi2388wmkwe
clientSecret: kksd23isdmsisdi2
resource:
userInfoUri: http://localhost:9999/uaa/user
zuul:
routes:
auth-server: /auth-server/**
resource: /resource/**
zuul app:
#SpringBootApplication
#EnableZuulProxy
#EnableOAuth2Sso
public class Application extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.logout().permitAll()
.and().authorizeRequests()
.mvcMatchers("/login/**").permitAll()
.anyRequest().authenticated();
}
}
problem:
after logged in:
can access: AuthServer "http://localhost:8080/auth-server/uaa/user" and "http://localhost:8080/api/test"
but when access_token expired,
can oly access: "http://localhost:8080/api/test",
when accessing AuthServer "http://localhost:8080/auth-server/uaa/user" met error--
<error_description>
Access token expired: 530c9247-2331-47e3-a6c0-ed61814642f5
</error_description>
<error>invalid_token</error>
and I can't get access_token from request header,
How to resolve?
Before everything check your OAUTH server application server and your client application server time and timezone if they are separated in two different machine.
Your OAUTH Server Configuration I think has some problems. OAUTH Server itself is secured with 'BASIC ACCESS AUTHENTICATION' : https://en.wikipedia.org/wiki/Basic_access_authentication
Which works with a token on his requests headers :
'Authorization' : Basic=Base64.encode(username+' '+password).
If you miss this token then you can't access any endpoint on your OAUTH server.
Mine works fine, you can test it:
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.formLogin().loginPage("/login").permitAll()
.and().requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/fonts/**", "/css/**")
.and().authorizeRequests().antMatchers("/fonts/**", "/css/**").anonymous().anyRequest().authenticated();
// #formatter:on
}
And why have you disabled csrf protection?
these are my token store configuration :
#Autowired
#Qualifier("datasource")
private DataSource dataSource;
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
#Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authorizationCodeServices(authorizationCodeServices())
.authenticationManager(authenticationManager).tokenStore(tokenStore())
.approvalStoreDisabled();
}

Resources