Spring boot + OAuth2, Throw server_error - spring-boot

I'm getting internal server error while running my code. i have no idea what happened because It shows nothing in console.
here my AuthorizationServerConfig class
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private DataSource dataSource;
#Autowired
private AuthenticationManager authenticationManager;
#Bean
TokenStore jdbcTokenStore() {
return new JdbcTokenStore(dataSource);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()").tokenKeyAccess("permitAll()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jdbcTokenStore());
endpoints.authenticationManager(authenticationManager);
}
}
here my websecurityconfig code
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean
protected AuthenticationManager getAuthenticationManager() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public static PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
this is my userserviceImpl
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserDetailRepository userDetailRepository;
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Optional<User> optionalUser = userDetailRepository.findByUsername(name);
optionalUser.orElseThrow(() -> new UsernameNotFoundException("Username or password wrong"));
UserDetails userDetails = new AuthUserDetail(optionalUser.get());
new AccountStatusUserDetailsChecker().check(userDetails);
return userDetails;
}
}
this is how i get token
http://localhost:8802/oauth/token?grant_type=password&username=abc&scope=READ&password=abc *
output
{
"error": "server_error",
"error_description": "Internal Server Error"
}

Related

spring boot oauth2 ResourceServerConfigurerAdapter not protecting resources

spring boot oauth2 ResourceServerConfigurerAdapter not protecting resourcs
/oauth/token working fine.
.antMatchers("/api/waiter/**") in resourceserver is accessible by public.
.antMatchers("/api/waiter/").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/").authenticated()
i have clearly defined role for api.
seem like problem in resource server configuration.
My Codes Are
#Configuration
#EnableResourceServer
#Order(2)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Value("${spring.datasource.driver-class-name}")
private String oauthClass;
#Value("${spring.datasource.url}")
private String oauthUrl;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
private static final String RESTRWAITER = "WAITER";
#Bean
public TokenStore tokenStore() {
DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
.password(password).url(oauthUrl).build();
return new JdbcTokenStore(tokenDataSource);
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("scout").tokenStore(tokenStore());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().requestMatchers().antMatchers("/api/waiter/**").and().authorizeRequests()
.antMatchers("/api/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/api/waiter/**").authenticated().and().exceptionHandling()
.accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
And
AuthorizationServerConfig
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Value("${spring.datasource.driver-class-name}")
private String oauthClass;
#Value("${spring.datasource.url}")
private String oauthUrl;
#Value("${spring.datasource.username}")
private String username;
#Value("${spring.datasource.password}")
private String password;
#Bean
public TokenStore tokenStore() {
System.out.println(username);
DataSource tokenDataSource = DataSourceBuilder.create().driverClassName(oauthClass).username(username)
.password(password).url(oauthUrl).build();
return new JdbcTokenStore(tokenDataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager);
endpoints.tokenStore(tokenStore());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()")
.allowFormAuthenticationForClients();
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("clientapp").secret(getPasswordEncoder().encode("123456"))
.authorizedGrantTypes("password", "authorization_code", "refresh_token").authorities("READ_ONLY_CLIENT")
.scopes("read_profile_info").resourceIds("oauth2-resource").redirectUris("http://localhost:8081/login")
.accessTokenValiditySeconds(120000).refreshTokenValiditySeconds(240000);
}
}
and
SecurityConfiguration
#Configuration
#EnableWebSecurity
#Order(1)
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String SYSTEM = "SYSTEM";
private static final String RESTRUSER = "RESTRO";
private static final String RESTRWAITER = "WAITER";
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
#Bean
public AuthenticationFailureHandler customAuthenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/api/waiter/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**").hasRole(SYSTEM).antMatchers("/restro/**")
.hasAnyRole(RESTRUSER).antMatchers("/waiter/**").hasAnyRole(RESTRWAITER).antMatchers("/", "/pub/**")
.permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/dashboard")
.failureHandler(customAuthenticationFailureHandler()).permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
.deleteCookies("my-remember-me-cookie").permitAll().and().rememberMe()
// .key("my-secure-key")
.rememberMeCookieName("my-remember-me-cookie").tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(24 * 60 * 60).and().exceptionHandling();
}
PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
tokenRepositoryImpl.setDataSource(dataSource);
return tokenRepositoryImpl;
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
The problem is resource server .antMatchers("/api/waiter/**") is accessible without access_token.
Resource server configuration not working.
Got found solution
just replaced #Order(1) with #Order(SecurityProperties.BASIC_AUTH_ORDER) on SecurityConfiguration . And its worked.
#Configuration
#EnableWebSecurity
#Order(SecurityProperties.BASIC_AUTH_ORDER)
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

SpringBoot OAuth2 error "Full authentication is required to access this resource"

I am trying to implement OAuth2 - SpringBoot authentication.
I have configured a path with permitAll(), but even though it is configured, it shows error
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
I am using postman to test and simply trying to fetch all users in DB. When I call, the control is not coming to RestController. I would like to just get the users list and permitAll() is provided.
Can anyone please help ?
I am posting the code below.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().
antMatchers(HttpMethod.POST, "/api/**").permitAll().
antMatchers(HttpMethod.POST,"/admin/**").hasAnyRole("ADMIN").
anyRequest().authenticated();
}
#Override
public void configure(AuthenticationManagerBuilder builder) throws Exception{
builder.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select usrnam,usrpwd, case when usrsta='A' then true else false end from chsusrmst where usrnam=?")
.authoritiesByUsernameQuery("select usrnam,usrtyp from chsusrmst where usrnam=?");
}
}
#RestController
#RequestMapping("/api")
public class UserController {
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#Autowired
private UserRepository userRepository;
#PostMapping("/user/register")
public String register(#RequestBody User user) {
String encodedPassword = passwordEncoder.encode(user.getUserPassword());
user.setUserPassword(encodedPassword);
userRepository.save(user);
return "User created";
}
#PostMapping("/admin/findUser")
public User findUser(#RequestBody User user) {
return userRepository.findByUserName(user.getUserName());
}
#PostMapping("/user/findAllUsers")
public List<User> findAllUsers() {
return userRepository.findAll();
}
}
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final PasswordEncoder passwordEncoder;
private final UserDetailsService userDetailsService;
#Value("${jwt.clientId:client}")
private String clientId;
#Value("${jwt.client-secret:secret}")
private String clientSecret;
#Value("${jwt.signing-key:123}")
private String jwtSigningKey;
#Value("${jwt.accessTokenValidititySeconds:43200}") // 12 hours
private int accessTokenValiditySeconds;
#Value("${jwt.authorizedGrantTypes:password,authorization_code,refresh_token}")
private String[] authorizedGrantTypes;
#Value("${jwt.refreshTokenValiditySeconds:2592000}") // 30 days
private int refreshTokenValiditySeconds;
public AuthorizationServerConfig(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder, UserDetailsService userDetailsService) {
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userDetailsService = userDetailsService;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.accessTokenValiditySeconds(accessTokenValiditySeconds)
.refreshTokenValiditySeconds(refreshTokenValiditySeconds)
.authorizedGrantTypes(authorizedGrantTypes)
.scopes("read", "write")
.resourceIds("api");
}
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.accessTokenConverter(accessTokenConverter())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager);
}
#Bean
JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
return converter;
}
}
#Configuration
#EnableResourceServer
public class ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer serverSecurityConfigurer) {
serverSecurityConfigurer.resourceId("api");
}
}
Thanks for your consideration. I found the issue. HttpSecurity configuration was missing in Resource server and it has been resolved by adding below section.
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/user**").permitAll()
.antMatchers("/user/**").permitAll()
.antMatchers("/admin**").hasAuthority("ADMIN")
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated();

Springboot + Oauth2 - Failed to find access token

Am getting Failed to find access token for token 9ccc7637-04af-469d-93b8-209cbfac4e49 issue printed in a console when i call http://localhost:8081/oauth/token . Please find attached images for reference .
I gave my best but could find the issue .
Where i click oauth\token the token details are getting stored in database , but still throws error.
Unable to do API calls with access token created.
Please find below code and correct me .
Configuration
public class AppConfig {
#Value("${spring.datasource.url}")
private String datasourceUrl;
#Value("${spring.datasource.driver-class-name}")
private String dbDriverClassName;
#Value("${spring.datasource.username}")
private String dbUsername;
#Value("${spring.datasource.password}")
private String dbPassword;
#Bean
public DataSource dataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(dbDriverClassName);
dataSource.setUrl(datasourceUrl);
dataSource.setUsername(dbUsername);
dataSource.setPassword(dbPassword);
return dataSource;
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource());
}
}
#Configuration
#EnableAuthorizationServer
public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private final AuthenticationManager authenticationManager;
#Autowired
private final BCryptPasswordEncoder passwordEncoder;
#Autowired
private final UserDetailsService userService;
#Autowired
private TokenStore tokenStore;
public OAuthConfiguration(AuthenticationManager authenticationManager, BCryptPasswordEncoder passwordEncoder, UserDetailsService userService) {
this.authenticationManager = authenticationManager;
this.passwordEncoder = passwordEncoder;
this.userService = userService;
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.scopes("read","write","trust")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(50)
.refreshTokenValiditySeconds(1000)
.secret(passwordEncoder.encode("secret"));
}
#Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.userDetailsService(userService)
.authenticationManager(authenticationManager)
.tokenStore(tokenStore);
}
#Bean
public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
}
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.requestMatchers().antMatchers("/**").and()
.authorizeRequests()
.antMatchers("/**").access("hasRole('ADMIN') or hasRole('USER')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetails;
#Autowired
DataSource dataSource;
#Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).
usersByUsernameQuery("select username, password, enabled from users where username=?").
authoritiesByUsernameQuery("select username, roles from users where username=?");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/**").authenticated()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder( bCryptPasswordEncoder() );
provider.setUserDetailsService(userDetails);
return provider;
}
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/*
* #Autowired // here is configuration related to spring boot basic public void
* configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
* auth.inMemoryAuthentication() // static users
* .withUser("User").password(bCryptPasswordEncoder().encode("User")).
* roles("USER") .and()
* .withUser("Admin").password(bCryptPasswordEncoder().encode("Admin[")).
* roles("ADMIN"); }
*/
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetails)
.passwordEncoder(bCryptPasswordEncoder());
}
}
error in console :
enter image description here

access denied while using jwt token in spring security with oauth2

I am getting access denied on accessing request based on role. I don't know why. I am using spring security with oauth2 in spring boot.
The configured authorization server is -
#EnableAuthorizationServer
#Configuration
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authManager;
#Autowired
private AuthConfig config;
#Autowired
private UserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient(config.getClientId()).secret("{noop}".concat(config.getClientSecret()))
.scopes("read", "write").authorizedGrantTypes("password", "refresh_token")
.accessTokenValiditySeconds(config.getAccessTokenValidity())
.refreshTokenValiditySeconds(config.getRefresTokenValidity());
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.pathMapping("/oauth/token", config.getAuthPath());
endpoints.authenticationManager(authManager).tokenStore(tokenStore()).accessTokenConverter(jwtTokenEnhancer());
endpoints.userDetailsService(userDetailsService);
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
#Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"),
config.getKeyStorePassword().toCharArray());
JwtAccessTokenConverter converter = new CustomTokenEnhancer();
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
return converter;
}
}
and resource server is configured as
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "my_rest_api";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/create/user").permitAll().antMatchers("/hello").hasRole("superadmin")
.anyRequest().authenticated().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
}
}
and sever security configured as
#Configuration
#EnableWebSecurity(debug = true)
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
and decoded data in generated token is
{
"exp": 1547123578,
"user_name": "superadmin",
"authorities": [
{
"authority": "ROLE_superadmin"
}
],
"jti": "e1f6e67c-16b8-4a12-a300-fae7f406359e",
"client_id": "pgcil",
"scope": [
"read",
"write"
]
}
but http request http://localhost:8089/hello with jwt token gives acccess denied error. May anyone tell me what i am doing wrong.Any help would be appreciated.

Problems Injecting Custom Authentication Manager

I'm attempting to use a custom authentication manager but the standard Provider manager is being called to .authenticate. I suspect it has something to do with either the AuthSever or Web Config. Any help is greatly appreciated.
AuthServer configuration:
#Configuration
#EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private final DataSource dataSource;
#Autowired
public AuthServerConfig(DataSource dataSource){
this.dataSource = dataSource;
}
#Autowired
MicrosJwtConfig microsJwtConfig;
#Autowired
#Qualifier("microsProviderManager")
AuthenticationManager authenticationManager;
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder(10);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.tokenServices(microsJwtConfig.microsTokenServices())
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.allowFormAuthenticationForClients();
security.passwordEncoder(encoder());
security.tokenKeyAccess("permitAll()");
}
}
WebSecurity config:
#EnableWebSecurity
#Configuration
public class WebSecConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private MECAuthenticationProvider mecAuthenticationProvider;
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return new MicrosProviderManager(clientDetailsService, mecAuthenticationProvider );
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("actuator/health").permitAll().and()
.authorizeRequests().antMatchers("oauth/token").permitAll().and()
.authorizeRequests().antMatchers("actuator/info").permitAll();
}
}

Resources