User can access resource even if he's not part of "#Secured([role])" - spring-security

I would like to secure my endpoint so only users with the role READ can access a certain resource. Those are my configurations:
Controller:
#RestController
#RequestMapping("/api/status")
public class StatusController {
#RequestMapping(method = RequestMethod.GET)
#Secured("READ")
Map<String, Object> getSecureStatus() {
Map<String, Object> statusMap = new LinkedHashMap<>();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
statusMap.put("auth", auth);
return statusMap;
}
}
The WebSecurityConfigurerAdapter:
#Configuration
#EnableGlobalMethodSecurity(securedEnabled = true)
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// .antMatchers("/").permitAll()
.antMatchers("/api/**").authenticated()
.and()
.httpBasic();
}
}
GlobalAuthenticationConfigurerAdapter:
#Configuration
public class AuthenticationManagerConfig extends
GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("teddy").password("password").roles("USER");
}
}
I would assume that Teddy shouldn't be able to access the resource, as his role is USER rather than READ.
But with this call, Teddy gets his information anyway:
curl -u teddy:password 'http://localhost:8080/api/status/':
{
"auth": {
"details": {
"remoteAddress": "127.0.0.1",
"sessionId": null
},
"authorities": [
{
"authority": "ROLE_USER"
}
],
"authenticated": true,
"principal": {
"password": null,
"username": "teddy",
"authorities": [
{
"authority": "ROLE_USER"
}
],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
},
"credentials": null,
"name": "teddy"
}
}
What am I missing?
Edit: removed .antMatchers("/").permitAll()

Probably it's because you're using .antMatchers("/").permitAll() it's telling spring that you're allowing every request.
Try removing it from your configuration.

I found the mistake. I overlooked that getSecureStatus() wasn't explicitely defined public. This code fixes it:
#RestController
#RequestMapping("/api/status")
public class StatusController {
#RequestMapping(method = RequestMethod.GET)
#Secured("READ")
public Map<String, Object> getSecureStatus() {
Map<String, Object> statusMap = new LinkedHashMap<>();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
statusMap.put("auth", auth);
return statusMap;
}
}

Related

Spring GraphQL authentication error handling

I am using Spring GraphQL and Spring Security in my project. I am authenticating users with JWTs so I have a security filter to check the validity of the token. When the token is invalid, an exception is thrown.
I am trying to return the message of the exception as a valid graphQL response but all I get is this:
{
"errors": {
"message": "Failed to execute 'text' on 'Response': body stream already read",
"stack": "TypeError: Failed to execute 'text' on 'Response': body stream already read\n at http://localhost:8080/graphiql?path=/graphql:78:33"
}
}
The error I am getting in the console is this:
com.auth0.jwt.exceptions.JWTDecodeException: The input is not a valid base 64 encoded string.
So, I want that in the "errors" "message".
This is the Security configuration:
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AppUserDetailsService appUserDetailsService;
private final JwtFilter jwtFilter;
public SecurityConfig(AppUserDetailsService appUserDetailsService, JwtFilter jwtFilter) {
this.appUserDetailsService = appUserDetailsService;
this.jwtFilter = jwtFilter;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(appUserDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth").permitAll()
.antMatchers("/graphiql").permitAll()
.antMatchers("/graphql").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
and this is the jwtFilter:
#Log4j2
#Component
public class JwtFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
private final AppUserDetailsService userDetailsService;
public JwtFilter(JwtUtil jwtUtil, AppUserDetailsService userDetailsService) {
this.jwtUtil = jwtUtil;
this.userDetailsService = userDetailsService;
}
#Override
protected void doFilterInternal(#NotNull HttpServletRequest request,
#NotNull HttpServletResponse response,
#NotNull FilterChain filterChain) throws ServletException, IOException {
final String header = request.getHeader("Authorization");
String username = null;
String jwt = null;
try {
if (header != null && header.startsWith("Bearer ")) {
jwt = header.substring(7);
username = jwtUtil.getUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
} catch (Exception ex) {
log.error(ex.getMessage());
throw ex;
}
filterChain.doFilter(request, response);
}
}
Does anyone know how could I achieve that?
Thanks!

SPRING-SECURITY Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’

I have my service work and deployed with no problem, but i need to add more feature [Realtime Notification]. I'm using SockJS, StompJS, Spring security, and LDAP authentication.
Here is my AuthenticationFilter, i'm using token as my passcode it generated after login into LDAP.
#Log4j2
public class AuthenticationFilter extends OncePerRequestFilter {
#Autowired
private JWTUtil jwtUtil;
private final String authHeader = "token";
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
//CORS
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Headers", "token");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
}
final String authHeader = request.getHeader(this.authHeader);
if (authHeader != null) {
String token = authHeader;
try {
Claims claims = jwtUtil.getAllClaimsFromToken(token);
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
new User(claims.getSubject()),
null,
authorities
);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
log.debug("Error ", e);
}
}
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
chain.doFilter(request, response);
}
}
}
Here is my WebSecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public UnauthorizedHandler unauthorizedHandler() throws Exception {
return new UnauthorizedHandler();
}
#Bean
public ForbiddenHandler forbiddenHandler() throws Exception {
return new ForbiddenHandler();
}
#Bean
public AuthenticationFilter authenticationFilterBean() throws Exception {
return new AuthenticationFilter();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler()).and()
.exceptionHandling().accessDeniedHandler(forbiddenHandler()).and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
// allow auth url
.antMatchers("/login","/v2/api-docs", "/configuration/ui", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html", "/webjars/**", "/notif/**", "/mealnotif/**", "/topic/**", "/websocket/**", "/resources/**", "/META-INF/resources/**").permitAll()
.anyRequest().authenticated();
// custom JWT based security filter
httpSecurity.addFilterBefore(authenticationFilterBean(), UsernamePasswordAuthenticationFilter.class);
// disable page caching
httpSecurity.headers().cacheControl();
}
}
And the last one is my WebSocketConfig
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/mealnotif");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notif").setAllowedOrigins("*")
.withSockJS();
}
}
But in return My Angular project always return Cross-Origin Request Blocked
CORS Reason ERROR
How do i solve this?
i can solve this by adding whitelist of allowed origin in my application.properties
management.endpoints.web.cors.allowed-origins=http://localhost,http://localhost:4200
by this properties i managed to giving properly response to client
response

Jhipster OAuth 2.0 / OIDC Authentication Authorization header with bearer token

I’ve used Jhipster to generate an app with the security option OAuth 2.0 / OIDC Authentication. I reconfigured said app to use Okta instead of keycloak following the instructions at http://www.jhipster.tech/security/#okta. All works as expected and the login flow performs as expected.
I now want to use OAuth 2.0 access_tokens to access my api resources from additional clients (Postman, Wordpress). I’ve retrieved a valid token from Okta added it to my Postman get request for localhost:8080/api/events and get a 401 in response.
The logs (https://pastebin.com/raw/R3D0GHHX) show that the spring security oauth2 doesn’t seem to be triggered by the presence of the Authorization bearer token.
Does Jhipster with OAuth 2.0 / OIDC Authentication support
access_token in the Authorization bearer header or url param out of
the box?
If not can you suggest what additional configurations I should make?
OAuth2Configuration.java
#Configuration
#Profile("dev")
public class OAuth2Configuration {
public static final String SAVED_LOGIN_ORIGIN_URI = OAuth2Configuration.class.getName() + "_SAVED_ORIGIN";
private final Logger log = LoggerFactory.getLogger(OAuth2Configuration.class);
#Bean
public FilterRegistrationBean saveLoginOriginFilter() {
Filter filter = new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if (request.getRemoteUser() == null && request.getRequestURI().endsWith("/login")) {
String referrer = request.getHeader("referer");
if (!StringUtils.isBlank(referrer) &&
request.getSession().getAttribute(SAVED_LOGIN_ORIGIN_URI) == null) {
log.debug("Saving login origin URI: {}", referrer);
request.getSession().setAttribute(SAVED_LOGIN_ORIGIN_URI, referrer);
}
}
filterChain.doFilter(request, response);
}
};
FilterRegistrationBean bean = new FilterRegistrationBean(filter);
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
#Bean
public static DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
return new DefaultRolesPrefixPostProcessor();
}
public static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FilterChainProxy) {
FilterChainProxy chains = (FilterChainProxy) bean;
for (SecurityFilterChain chain : chains.getFilterChains()) {
for (Filter filter : chain.getFilters()) {
if (filter instanceof OAuth2ClientAuthenticationProcessingFilter) {
OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter =
(OAuth2ClientAuthenticationProcessingFilter) filter;
oAuth2ClientAuthenticationProcessingFilter
.setAuthenticationSuccessHandler(new OAuth2AuthenticationSuccessHandler());
}
}
}
}
return bean;
}
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
#Override
public int getOrder() {
return PriorityOrdered.HIGHEST_PRECEDENCE;
}
}
}
SecurityConfiguration.java
#Configuration
#Import(SecurityProblemSupport.class)
#EnableOAuth2Sso
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
#Bean
public AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler() {
return new AjaxLogoutSuccessHandler();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**")
.antMatchers("/h2-console/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler())
.permitAll()
.and()
.headers()
.frameOptions()
.disable()
.and()
.authorizeRequests()
.antMatchers("/api/profile-info").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/websocket/**").permitAll()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN);
}
#Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
}
application.yml
security:
basic:
enabled: false
oauth2:
client:
access-token-uri: https://dev-800787.oktapreview.com/oauth2/ausb3ecnmsz8Ucjqw0h7/v1/token
user-authorization-uri: https://dev-800787.oktapreview.com/oauth2/ausb3ecnmsz8Ucjqw0h7/v1/authorize
client-id: <okta-client-id>
client-secret: <okta-client-secret>
client-authentication-scheme: form
scope: openid profile email
resource:
filter-order: 3
user-info-uri: https://dev-800787.oktapreview.com/oauth2/ausb3ecnmsz8Ucjqw0h7/v1/userinfo
token-info-uri: https://dev-800787.oktapreview.com/oauth2/ausb3ecnmsz8Ucjqw0h7/v1/introspect
prefer-token-info: false
server:
session:
cookie:
http-only: true
Matt's answer point me to the right direction, thanks!
and here is my current working configuration:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
#Configuration
#EnableResourceServer
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class OAuth2AuthenticationConfiguration extends ResourceServerConfigurerAdapter {
#Bean
public RequestMatcher resources() {
return new RequestHeaderRequestMatcher("Authorization");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatcher(resources())
.authorizeRequests()
.anyRequest().authenticated();
}
}
This answer was helpful too, thanks.
You need to use Spring Security OAuth's #EnableResourceServer for this functionality. If you're using Okta, you can also try using its Spring Boot Starter.

Spring OAuth2 AcessDenied while sending request with acess token

I have receivied access token with below request.
curl -X POST -H "Content-Type: application/json" -H "Authorization: Basic dHJ1c3RlZC1jbGllbnQ6c2VjcmV0" -H "Cache-Control: no-cache" -H "Postman-Token: 99a69c90-d7f0-64ae-bc8e-f682e84c58c3" "http://localhost:9090/oauth/token?grant_type=password&username=admin&password=admin123"
Below is the response
{
"access_token": "597147a1-bf8a-47f5-bd22-74ea1cd1df8f",
"token_type": "bearer",
"refresh_token": "de680b4a-e94e-460a-8853-be1aa5a264a3",
"expires_in": 4972,
"scope": "read write trust"
}
But when I am sending request with acess token getting 403.
Error while sending get request.
{
"timestamp": 1477034937446,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/user/customers"
}
while sending get requests.
curl -X GET -H "Authorization: Bearer 597147a1-bf8a-47f5-bd22-74ea1cd1df8f" -H "Cache-Control: no-cache" -H "Postman-Token: 7d8dfa60-8aeb-90ad-1bbe-433b52ef8306" "http://localhost:9090/user/customers"
I have used Mongo DB, Morphia as User acess. Redis is used as token store. But authentication is not working.
Below is the spring related configuration
#Configuration
#EnableAuthorizationServer
#ComponentScan(value = "com.guddi.muneeb")
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private static String REALM = "MUNEEB_OAUTH_REALM";
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("trusted-client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT","ADMIN")
.scopes("read", "write", "trust").resourceIds("MUNEEB_OAUTH_REALM")
.secret("secret")
.accessTokenValiditySeconds(6000).//Access token is only valid for 10 minutes.
refreshTokenValiditySeconds(12000);//Refresh token is only valid for 20 minutes.
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm(REALM + "/client");
}
}
OAuth:
#Configuration
#EnableWebSecurity
#ComponentScan(value = "com.guddi.muneeb")
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
ClientDetailsService clientDetailsService;
#Autowired
SecUserDetailsService userDetailsService;
#Autowired
public void configAuthBuilder(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/user/**").authenticated()
//.anyRequest().hasRole("ADMIN").and()
//.anyRequest().permitAll()
//.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Autowired
public JedisConnectionFactory jedisConnectionFactory;
#Bean
public TokenStore tokenStore() {
return new RedisTokenStore(jedisConnectionFactory);
}
#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;
}
}
Resource Server Configuration
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "muneeb_resource";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
//anonymous().disable()
.requestMatchers().antMatchers("/muneeb/**")
//.requestMatchers().antMatchers("/muneeb/user/**")
//.requestMatchers().antMatchers("/muneeb/admin/**")
.and().authorizeRequests()
//.antMatchers("/muneeb/admin/**").access("hasRole('ADMIN')")
//.antMatchers("/muneeb/user/**").access("hasRole('ADMIN')")
.antMatchers("/muneeb/**").access("hasRole('ADMIN')")
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
//.anyRequest().permitAll();
}
}
UserDetails implementations
#Service
public class SecUserDetails implements UserDetails {
private User user;
public SecUserDetails() {
super();
}
public SecUserDetails(User user) {
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for (String role : user.getRoles()) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role);
authorities.add(grantedAuthority);
}
//LOGGER.debug("user authorities are " + authorities.toString());
return authorities;
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return user.isAccountNonExpired();
}
#Override
public boolean isAccountNonLocked() {
return user.isAccountNonLocked();
}
#Override
public boolean isCredentialsNonExpired() {
return user.isCredentialsNonExpired();
}
#Override
public boolean isEnabled() {
return user.isEnabled();
}
Please help me. If I am missing something.
Thanks in advance

Spring OAuth2 autorization from database

Hello everyone,
I'm practicing OAuth2 in Spring boot.I have developed the application when i access get resources, i'm getting the response but for post resources i have to provide username and password which i'm passing in request but it still gives me this response
curl -i --user admin:admin -H Accept:application/json -X PUT http://localhost:8080/api/user/addUpdateUser -H Content-Type: application/json -d '{ "userId": 3, "firstName": "M.Danish", "lastName": "Khan", "userName": "danishkhan", "address": "Mardan", "phone": "04543545435" }'
{
"timestamp": 1464778621656,
"status": 401,
"error": "Unauthorized",
"message": "Access Denied",
"path": "/api/user/addUpdateUser"
}
This my code.
Web Security Configuration
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private UserDetailsService userDetailsService;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET).permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.and().csrf().disable();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
OAuth Resource Server Configuration
#Configuration
#EnableResourceServer
public class OAuth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private final String RESOURCE_ID="SpringOAuth";
#Autowired
private CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
/*#Autowired
private UserDetailsService userDetailsService;*/
#Override
public void configure(HttpSecurity http) throws Exception {
http .exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET).permitAll()
.anyRequest().authenticated()
/*.and().userDetailsService(userDetailsService); was just checking whether it will work with this or not*/
}
#Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
}
OAuth Authorization Server Configuration
#Configuration
#EnableAuthorizationServer
public class OAuth2AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
private final String RESOURCE_ID="SpringOAuth";
private TokenStore tokenStore = new InMemoryTokenStore();
#Autowired
private UserDetailsService userDetailsService;
#Autowired
AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("password", "refresh_token")
.authorities("ROLE_USER")
.scopes("read")
.resourceIds(RESOURCE_ID)
.secret("secret").accessTokenValiditySeconds(3600);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
Controller
#Controller
#RequestMapping("/api/user")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "/addUpdateUser",method = RequestMethod.POST)
public ResponseEntity<Void> add_UpdateUser(#RequestBody User user){
if(user==null){
return new ResponseEntity<Void>(HttpStatus.EXPECTATION_FAILED);
}else{
userService.add_UpdateUser(user);
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
}
#RequestMapping("/getAllUser")
public ResponseEntity<List<User>> getAllUsers(){
return new ResponseEntity<List<User>>(userService.getAllUsers(),HttpStatus.OK);
}
#RequestMapping(value = "/deleteUser",method = RequestMethod.POST)
public ResponseEntity<Void> deleteUser(#RequestBody String userName){
if(userName.equals("")){
return new ResponseEntity<Void>(HttpStatus.BAD_REQUEST);
}else {
userService.deleteUser(userName);
return new ResponseEntity<Void>(HttpStatus.OK);
}
}
}
Your content type header must be surround by quotation marks because you have a space in it.
-H Content-Type: application/json
Should be
-H "Content-Type: application/json"
Otherwise the shell considers them as separate arguments. Like this
$ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer 27f9e2b7-4441-4c03-acdb-7e7dc358f783" -d '{"apiKey": "key", "tag": "tag"}' localhost:8080/isTagAvailable
Also you didn't get an access token first.

Categories

Resources