Spring Boot #CrossOrigin annotation not working - spring

I am using Spring 2.6.6 and Reactjs for frontend. I have a POST endpoint exposed using a rest controller but is is giving CORS error when api is called
Below is the rest controller
#RestController
#CrossOrigin(origins = "http://localhost:3000", allowedHeaders = "*")
#RequestMapping("/image")
public class ImageUpload {
#Autowired
private ExtractData extractData;
#Autowired
private Gson gson;
#PostMapping("/extract")
public Map<String, ArrayList<String>> upload(
#RequestParam(value = "image") MultipartFile image,
#RequestParam(value = "selectedOptions") String selectedOptions
) throws IOException, TesseractException {
Map<String, Boolean> selectedOptionsMap = gson.fromJson(selectedOptions, Map.class);
byte[] imageData = image.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
try {
BufferedImage bufferedImage = ImageIO.read(bais);
Map<String, ArrayList<String>> resultSet = new HashMap<String, ArrayList<String>>();
resultSet = extractData.extractData(selectedOptionsMap, bufferedImage);
return resultSet;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Also implemented WebMvcConfigurer as follows but this also didn't work:
#Configuration
#EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/image/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST")
.allowedHeaders("*")
.allowCredentials(false).maxAge(3600);
}
}
My security configuration class
#EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService myUserDetailsService;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
#Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Request headers:
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 110239
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryX8BGweBFqsM2R7hy
Host: localhost:8080
Origin: http://localhost:3000
Referer: http://localhost:3000/
sec-ch-ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36
Response headers:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Sun, 03 Jul 2022 13:37:57 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Also adding CORS filter implementation did not work

I was missing http.cors() in the security configuration
Changing the configure method as follows solved the problem
#Override
public void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

Related

Why I get cors error when submitting a request to secured resource in spring boot?

I have implemented spring security in my app using jwt token, I have the following configuration in spring security:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
prePostEnabled = true)
public class MSSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/companies/UnAuth/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/companies/Auth/**").authenticated()
.antMatchers("/companies/Auth/Update").authenticated()
.antMatchers("/companies/Auth/Delete").authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
I have the following cors annotation on the relevant controller:
#CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
#RestController
#RequestMapping("/companies")
#Slf4j
public class CompanyController {
I tried to add the following to the http interceptor in angular:
authReq.headers.set("Access-Control-Allow-Origin", "http://localhost:4200");
authReq.headers.set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
When submitting the request from Angular 9 app I can't pass the security and I get cors error:
`Access to XMLHttpRequest at 'http://localhost:9001/companies/Auth/Update' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resourc`e.
The request doesn't contain the 'Access-Control-Allow-Origin' header, you should add it in the headers, it allows remote computers to access the content you send via REST.
If you want to allow all remote hosts to access your api content you should add it like so:
Access-Control-Allow-Origin: *
Your can also specify a specific host:
Access-Control-Allow-Origin: http://example.com
You should modify your dependencies in the pom.xml file and allow CORS headers, appart from the Access-Control-Allow-Origin headers there are a few more that you will need to add to the request, seek more info here:
https://spring.io/blog/2015/06/08/cors-support-in-spring-framework

Spring security basic authentication configuration

I've been trying to follow this tutorial :
https://www.baeldung.com/spring-security-basic-authentication
I have created a couple of rest endpoints like this :
#RestController
public class PostController {
#Autowired
PostCommentService postCommentService;
#Autowired
PostService postService;
#GetMapping("/comment")
public PostComment getComment(#RequestParam Long id) {
return postCommentService.findPostCommentById(id);
}
#PostMapping("/createPost")
public void createPost(#RequestBody PostDTO body){
postService.createPost(body);
}
}
Now for security I am using spring like this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
This is the config class for spring security:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers( "/comment").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("password"))
.authorities("ROLE_USER");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
The CustomFilter looks like this:
public class CustomFilter extends GenericFilterBean {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
And this is the AuthenticationEntryPoint:
#Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException {
response.addHeader("WWW-Authenticate", "Basic realm= + getRealmName() + ");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter writer = response.getWriter();
writer.println("HTTP Status 401 - " + authEx.getMessage());
}
#Override
public void afterPropertiesSet(){
setRealmName("spring");
super.afterPropertiesSet();
}
}
Now the problem is that whenever I try to send a POST request I end up getting this error message:
HTTP Status 401 - Full authentication is required to access this resource
I have tried two approaches to send the request, one via postman
And the second one via curl:
curl -i --user admin:password --request POST --data {"text":"this is a new Post"} http://localhost:8080/createPost
I am at my wits' end here, hence the need to create this post. Any help will be much appreciated.
This is the curl response in case it might shed light on the matter:
1.1 401
Set-Cookie: JSESSIONID=6FE84B06E90BE7F2348C0935FE3DA971; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Basic realm= + getRealmName() +
Content-Length: 75
Date: Thu, 10 Sep 2020 13:47:14 GMT
HTTP Status 401 - Full authentication is required to access this resource
This happens because Spring Security comes with CSRF protection enabled by default (and for a good reason). You can read about Cross Site Request Forgery here. In your case the CsrfFilter detects missing or invalid CSRF token and you're getting the 401 response. The easiest way to make your example work would be to disable csrf-ing in your security configuration but, of course, you shouldn't do this in a real application.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers( "/comment").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}

Digest authentication with spring security: 401 recieved as expected but with two WWW-Authenticate headers

When I send PUT request with correct username and password, it works fine.
But when I send request with wrong password, I received 401 which is ok, but in I got 2 WWW-Authenticate headers:
Response headers:
HTTP/1.1 401
WWW-Authenticate: Digest realm="NOKIA.COM", qop="auth", nonce="MTU1MjM3MDk2MDQ2MjpmOWNjYjVmNGU5ODA0ZmY0YWY0MjIxNDlhY2U2ODJiMQ=="
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
WWW-Authenticate: Digest realm="NOKIA.COM", qop="auth", nonce="MTU1MjM3MDk2MDQ2NjoxOTQ4MDhjNzBjYjkyMGI1Y2Q2YjU3OGMyMTM2NmE3OQ=="
Content-Length: 0
Date: Tue, 12 Mar 2019 06:08:20 GMT
#EnableWebSecurity
#Configuration
#Component
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
#Autowired
DummyUserService userDetail;
#Autowired
DigestAuthenticationFilter digestFilter;
#Autowired
DigestAuthenticationEntryPoint digestEntryPoint;
#Override
protected void configure( HttpSecurity http ) throws Exception
{
http.addFilter(digestFilter) // register digest entry point
.exceptionHandling().authenticationEntryPoint(digestEntryPoint) // on exception ask for digest authentication
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable();
http.httpBasic().disable();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
#Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
#Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}
}
#Bean
DigestAuthenticationFilter digestFilter( DigestAuthenticationEntryPoint digestAuthenticationEntryPoint,
UserCache digestUserCache, UserDetailsService userDetailsService )
{
DigestAuthenticationFilter filter = new DigestAuthenticationFilter();
filter.setAuthenticationEntryPoint( digestAuthenticationEntryPoint );
filter.setUserDetailsService( userDetailsService );
filter.setUserCache( digestUserCache );
return filter;
}
#Bean
UserCache digestUserCache() throws Exception
{
return new SpringCacheBasedUserCache( new ConcurrentMapCache( "digestUserCache" ) );
}
#Bean
DigestAuthenticationEntryPoint digestAuthenticationEntry()
{
DigestAuthenticationEntryPoint digestAuthenticationEntry = new DigestAuthenticationEntryPoint();
digestAuthenticationEntry.setRealmName( "XXX.COM" );
digestAuthenticationEntry.setKey( "XXX" );
digestAuthenticationEntry.setNonceValiditySeconds( 60 );
return digestAuthenticationEntry;
}
Please someone can give me some help. Many thanks!
I solved this problem by myself. For request with incorrect auth, DigestAuthenticationEntryPoint was called twice by both digestFilter and exceptionFilter.
Overwrite DigestAuthenticationEntryPoint:
public class CustomDigestAuthenticationEntryPoint extends DigestAuthenticationEntryPoint
{
#Override
public void commence( HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException )
throws IOException, ServletException
{
HttpServletResponse httpResponse = ( HttpServletResponse ) response;
String authHeader = httpResponse.getHeader( "WWW-Authenticate" );
if( authHeader != null )
{
httpResponse.sendError( HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase() );
}
else
{
super.commence( request, httpResponse, authException );
}
}
}

Spring security 4.2.3, OAUTH 2, /oauth/token endpoint, CORS not working

Angular 5 app needs to login a user. Token request is sent to /oauth/token. The preflight OPTIONS request(sent by Chrome) fails because of CORS.
I tried to follow the examples at Spring Security 4.2 and various questions and responses on Stackoverflow.
Here is my code :
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://example.com"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
............
}
And here is the request from Chrome
General Headers
Request URL: http://api.example.com/oauth/token
Request Method: OPTIONS
Status Code: 401
Remote Address: 127.65.43.21:80
Referrer Policy: no-referrer-when-downgrade
Request headers
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: api.example.com
Origin: http://example.com
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
Response:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Language: en
Content-Length: 1111
Content-Type: text/html;charset=utf-8
Date: Mon, 07 May 2018 03:23:15 GMT
Expires: 0
Pragma: no-cache
WWW-Authenticate: Basic realm="MY_REALM"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
And the error in console:
Failed to load http://api.example.com/oauth/token: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access. The response had HTTP status code 401.
I could not make it work with the CorsFilter provided by Spring.
The work around here helped.
Spring security, cors error when enable Oauth2
The part of final code
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
#WebFilter("/*")
public class SimpleCORSFilter implements Filter {
public SimpleCORSFilter() {
}
#Override
public void init(FilterConfig fc) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
System.out.println("doFilter");
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, origin, x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, resp);
}
}
#Override
public void destroy() {
}
}
In the security configuration:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/oauth/token");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
//.cors().and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
}
/*
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://example.com"));
configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"));
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}*/
............
}
I am still waiting for an example that makes it work with Spring Security's CorsFilter.
Instead of what you have done, write a custom cors filter like the following
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN);
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}
And modify your configure(HttpSecurity http) override to
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.and()
.csrf().disable()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/signup").permitAll()
.antMatchers("/oauth/token").permitAll()
.antMatchers("/fapi/**").authenticated()
.and()
.httpBasic()
.realmName("MY_REALM");
}

Unable to do file upload on RestController behind SpringSecurity (got 404)

Im trying to do fileupload (via RestController and also had tried with Controller), but it always returns a 404.
There is a reverse proxy in front of this app, hence entry point is /v2/service.
All the other API calls are working fine, except for this file upload. Please advise.
My Configuration
#Configuration
#ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
#ConditionalOnProperty(prefix = "multipart", name = "enabled", matchIfMissing = true)
#EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {
#Autowired
private MultipartProperties multipartProperties = new MultipartProperties();
#Bean(name="multipartResolver")
public CommonsMultipartResolver getResolver() throws IOException{
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSizePerFile(1242880);
return resolver;
}
#Bean
#ConditionalOnMissingBean
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
#Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
#ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
And my controller: (i have tried RestController and Controller, both gave me 404)
#RestController
public class UploadController {
#Autowired
private ImageService imageService;
#RolesAllowed({ "ROLE_USER" })
#RequestMapping(value="/api/item/image/u", method=RequestMethod.POST)
public String handleFileUpload(#RequestPart("file") MultipartFile file) throws ImageSizeException, IOException{
System.out.println("Upload start : ");
returns "YEY";
}
}
A snippet of my spring security config:
#Configuration
public class OAuth2ServerConfiguration {
private static final String RESOURCE_ID = "batmanservice";
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
// #formatter:off
resources.resourceId(RESOURCE_ID);
// #formatter:on
}
#Override
public void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.authorizeRequests()
.antMatchers("/api").hasRole("USER")
.antMatchers("/batsearch").anonymous();
http.csrf().disable();
// #formatter:on
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
private TokenStore tokenStore = new InMemoryTokenStore();
#Autowired
#Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
#Autowired
private UserService userService;
#Autowired
private CustomUserDetailsService userDetailsService;
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
// #formatter:off
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(this.userDetailsService);
// #formatter:on
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
// #formatter:off
clients
.inMemory()
.withClient("batclient")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.authorities("ROLE_USER")
.scopes("read", "write", "trust")
.accessTokenValiditySeconds(18000)
.resourceIds(RESOURCE_ID)
.secret("batmansecret");
// #formatter:on
}
#Bean
#Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
}
And here is how i tested using postman:
which is:
POST /v2/service/api/item/image/u?access_token=9105dbcd-00a4-4614-aa69-a53e83bc356e HTTP/1.1
Host: localhost:8080
Authorization: Basic YzNidTRwcDBuZTpGRjAxNURFQUQwNjVBMEEw
Cache-Control: no-cache
Postman-Token: 2ad8977e-842e-c442-e480-9004b9d21854
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename=""
Content-Type:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=""
------WebKitFormBoundary7MA4YWxkTrZu0gW--
In your UploadController implementation, #RequestMapping is at path "/api/item/image/u" but the api is called at "/service/api/item/image/u". I cannot see "service/" mapped anywhere as prefix or in your controller hence 404.

Resources