AWS Cognito Angular SpringBoot Oauth2 - invalid_token error - spring

we are using AWS Cognito for Oauth2. Our UI is built on Angular. After my user logs in, I initiate a call to Cognito to get Authorization token. I am using Authorization Code Grant with PKCE for getting the token from Cognito. After getting the toke from Cognito, I call my Spring Boot REST service. When calling Spring Boot service from Angular, I send the token in the Authorization header as "Bearer" token.
Here is my ResourceServerConfiguration.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource-server-rest-api";
private static final String SECURED_READ_SCOPE = "#oauth2.hasScope('openid')";
private static final String SECURED_WRITE_SCOPE = "#oauth2.hasScope('openid')";
private static final String SECURED_PATTERN = "/**";
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers(SECURED_PATTERN).and().authorizeRequests()
.antMatchers(HttpMethod.POST, SECURED_PATTERN).access(SECURED_WRITE_SCOPE)
.anyRequest().access(SECURED_READ_SCOPE);
}
}
When calling the REST service my Angular UI gets HTTP Response 401 with the following error message:
DEBUG o.s.s.o.p.a.OAuth2AuthenticationProcessingFilter - Authentication request failed: error="invalid_token", error_description="Invalid access token: eyJraWQiOiIy.......
Any idea why I am getting invalid_token?
Does spring makes a call to Cognito to verify the token?
I am NOT storing the token in my REST servic layer. Is this required?
I enabled DEBUG using logging.level.root=DEBUG. But I do not see descriptive message in the output. How do i trouble shoot this issue?

The below changes worked for me
Remove #EnableResourceServer
Add below to your spring security configuration
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS,"**").permitAll()
.anyRequest()
.authenticated()
.and().oauth2ResourceServer().jwt();
adding below 2 dependency to pom.xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
finally add following properties to your application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://cognito-idp.us-east-1.amazonaws.com/{{userpoolid}}
com:
ixortalk:
security:
jwt:
aws:
userPoolId: {{userpoolid}}
region: "us-east-1"

Related

Spring Boot with oauth2 using keycloak

I use spring boot as backend in addition to thymeleaf as the template engine. Atm, I'm trying to implement oauth2 (with keycloak) into my project.
I created a new realm, added a redirect-uri ("http://172.31.52.123:8000/*") + created users and put the id, secret, etc. in my application.properties file.
When I call http://172.31.52.123:8000/ I get the "hi" message from the ViewController below.
When I call http://172.31.52.123:8000/greeting, I will be redirected to http://172.31.52.123:8080/oauth2/authorization/appliance and then to the keycloak login. From there, I get these parameters:
response_type: code
client_id: myClientId
state: hpcfsknjW6QCfMSQWS-k...
redirect_uri: http://172.31.52.123:8080/*
and then these from keycloak again:
state: hpcfsknjW6QCfMSQWS-k...
session_state: f6ca95e5-a117-...
code: 298f32f-f283f ...
After the login, I end up with this:
172.31.52.123 hat Sie zu oft weitergeleitet. -> ERR_TOO_MANY_REDIRECTS
There is nothing in the console. What am I doing wrong? Originally, it should redirect to http://172.31.52.123:8000/*.
application.properties
appliance-base-url: https://authServerBlaBla/auth/realms/myRealmName
spring:
security:
oauth2:
client:
registration:
appliance:
authorizationGrantType: authorization_code
redirectUri: http://172.31.52.123:8080/*
clientId: myClientId
clientSecret: myClientSecret
provider:
appliance:
authorization-uri: ${appliance-base-url}/protocol/openid-connect/auth
token-uri: ${appliance-base-url}/protocol/openid-connect/token
user-info-uri: ${appliance-base-url}/protocol/openid-connect/userinfo
SecurityConfig
#EnableWebSecurity
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorizeRequests -> authorizeRequests
.mvcMatchers("/").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
}
ViewController
#Controller
public class ViewController {
#GetMapping(value = {"/"})
#ResponseBody
public String index() {
return "hi";
}
#GetMapping("/greeting")
#ResponseBody
public String greet() {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
return "Welcome, " + username;
}
}
You return #ResponseBody => your app should be configured as resource-server (not client).
If your app also serves UI elements (with Thymeleaf, JSF or whatever server-side rendering framework), you'll have to provide two different filter-chains, with securityMatcher patterns to specify where to apply resource-server security and where to apply client one.
I already detailed that in this answer: Use Keycloak Spring Adapter with Spring Boot 3
Details for configuring a Spring backend as both a resource-server (REST API served with #RestController) and a client (server-side rendered HTML with a regular WebMvc #Controller with Thymeleaf, JSF or whatever) in this one of my tutorials.
After having a look in the book:
Keycloak - Identity and Access Management for Modern Applications: Harness the Power of Keycloak, OpenID Connect, and OAuth 2.0 Protocols to Secure Applications
I figured that using Spring Boot + Thymeleaf requires keycloak to identify the application as a client. This might be the case in addition to the authorization code grant type.
All I had to do was the following:
change paths into relative paths (requests url)
remove/add proxies for the communication to work
add the following into your pom:
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>3.0.0</version>
</dependency>
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.0.0</version>
</dependency>
create an application.properties/yaml file with your configuration:
appliance-base-url: https://yourKeycloakInstance/auth/realms/p4udemo
spring:
security:
oauth2:
client:
registration:
democlient:
provider: keycloak
client-id: democlient
client-secret: 73... 324
authorization-grant-type: authorization_code
redirect-uri: "http://yourwebsite:port/login/oauth2/code/"
scope: openid
provider:
keycloak:
authorization-uri: ${appliance-base-url}/protocol/openid-connect/auth
token-uri: ${appliance-base-url}/protocol/openid-connect/token
jwk-set-uri: ${appliance-base-url}/protocol/openid-connect/certs
Add securityConfiguration.java (can be renamed differently):
#EnableWebSecurity
public class SecurityConfiguration {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest().authenticated()
)
.oauth2Login(withDefaults());
return http.build();
}
}

spring boot rest app secured by keycloak 18 return always error 401 Unauthorized

I'm developing microservices some of them with spring boot web and other with spring boot data rest and I want secure them with keycloak server 18 through OpenId protocol. The microservices endpoint can be accessed from frontend adding in the "Authorization header" the bearer token obtained from post request to the url http://localhost:8280/auth/realms/--realm_name--/.well-known/openid-configuration inserting in the body request the key client_id, username, password, grant_type, client_secret.
I have create
1.a realm,
2.a client named "springboot-mc-dev" (with Access Type = confidential;,
"Root URL" and "Valid Redirect URIs" both setted to "http://localhost:8490",
"Standard Flow Enabled", "Direct Access Grants Enabled", "Service Accounts Enabled" and "Authorization Enabled" setted to "ON"),
3.before a role inside client ("named springboot-mc-dev-role" composite False) and after a role inside realm (named always "springboot-mc-dev-role" composite true that is associated Client Roles "springboot-mc-dev-role" of client springboot-mc-dev),
4.user mapped to role "springboot-mc-dev-role" in "realm roles"
After I have imported the following dependency in parent pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java-version>1.8</java-version>
<keycloak.version>18.0.2</keycloak.version>
</properties>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>${keycloak.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Here there is the code of SecurityConfig.java class
package it.organization.project.microservice.datamart.config.security;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
#KeycloakConfiguration
#Configuration
#EnableWebSecurity
#Import(KeycloakSpringBootConfigResolver.class)
#EnableGlobalMethodSecurity(jsr250Enabled = true)
#ConditionalOnProperty(name = "ms-security-enable", havingValue = "true")
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
//keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
#Bean
#Override
/*protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}*/
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new NullAuthenticatedSessionStrategy();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/**").hasRole("springboot-mc-dev-role")
//.anyRequest().hasRole("springboot-mc-dev-role")
//.anyRequest().//authenticated()
//permitAll()
;
http.csrf().disable();
}
#Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
//public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
this is the code of main class
package it.organization.project.microservice.datamart;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
#SpringBootApplication
#EnableCaching
public class MAINDataMartApplication {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
SpringApplication.run(MAINDataMartApplication.class, args);
}
}
and last there is the application.yml with keycloak settings
#KEYCLOAK CONFIGURATION
keycloak:
auth-server-url: http://localhost:8280/auth
#ssl-required: external
realm: realmname
bearer-only: true
#public-client: true
use-resource-role-mappings: true
resource: springboot-mc-dev
credentials:
secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
this is the result
What is wrong?
Keycloak spring adapter is deprecated. Don't use it.
Have look at those tutorials for alternatives.
We are missing important info to answer preecisely:
Spring versions?
reason for 401 (from Postman console, value of WWW-Authenticate response header)?
There can be few reasons for 401 Unauthorized:
missing authorization header
expired or not yet valid token (for instance because of timezone misconfiguration on either authorization or resource server)
different issuer in access-token claim and Spring config: host, port, etc must be exactly the same
Spring configured for a different type of authentication than what authorization server supports (i.e. opaque token with introspaction and one side and JWT on the other)
...
If you're using Keycloak 18 with Quarkus, it is likely that your conf should reference http://localhost:8280 as issuer (and not http://localhost:8280/auth).
So, look at Postman console, open your access-token with a tool like https://jwt.io and compare values you find there with what you have in spring conf and logs.

How single authentication can work for multiple server nodes in Spring Security

I am using weblogic for deploying my spring boot application, and my same application is deployed on multiple nodes.
For example the two node in which the application is deployed is 9001 and 9002.
With basic security even if I am authenticated on the Node 9001 and trying to access the same URL on second node i.e on 9002, I am again getting redirected again to spring login page for authentication.
I want that once I authenticate using username and password on any node. I need not to authenticate again, Even if I am requesting to any other node.
Any kind of clue or help will be appreciated.
Thanks in advance.
The Security configuration file is
package com.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test")
.password("{noop}test")
.authorities("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/userdetail").authenticated()
.anyRequest().permitAll()
.and()
.formLogin();
}
}
In my case it worked for both node when I enabled RedisHttpSession.
Below is the code which worked for me.
#Configuration
#EnableRedisHttpSession
public class RedisConfig {
#Bean
public JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
}
also in pom.xml I needed to make two dependencies(For Spring boot).
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
You can also take reference about EnableRedisHttpSession from spring docs, and about spring session from
https://docs.spring.io/spring-session/docs/current/api/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.html
https://www.baeldung.com/spring-session

How to validate tokens received from authorization server

I have a oauth flow in my project.
I retrieve in the front-end a jwt token and add it to each request in the authorization header.
Now I need to validate said token and verify the signature in my back-end which is a kotlin spring boot app.
I know how to validate the token with the jjwt library but I don't understand where the validation is done.
I have a certificate to validate the tokens with and just want to let the requests with a valid token to be treated.
I saw online that some people do it with a OncePerRequestFilter that they add to their SecurityConfiguration but I don't understand what's going on and how it works.
I tried searching for tutorials online but many of them make a backend that's both the authorization server and resource server. I just want the backend to be the resource server that checks with the certificate if the token is valid and treats the request if it is. How can I do that ?
For now this is my SecurityConfiguration :
package com.renaulttrucks.transfertprotocolbackend.security.config
import org.springframework.beans.factory.annotation.Value
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
#EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
#Value("\${security.enabled}")
val securityEnabled : Boolean? = false
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
if(!securityEnabled!!) {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.csrf().disable()
.formLogin().disable()
} else {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/**").permitAll()
.and()
.csrf().disable()
.formLogin().disable()
}
}
}
Spring Security supports resource servers out-of-the-box when including the correct dependencies and configuration.
As #sdoxsee mentioned, there is a Spring Security sample that outlines how to create a resource server with a public key; however, I'll briefly summarize it here, though you can find more detail in the Spring Security reference.
First, you need to add the appropriate dependency. If you are a Spring Boot application, then you can add:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
Second, you either specify your key as a Boot property:
spring:
security:
oauth2:
resourceserver:
jwt:
public-key-location: classpath:my-key.pub
or, you configure a JwtDecoder with your public key directly:
#Configuration
class SecurityConfig {
#Value("${public.key.property}") val key : RSAPublicKey;
#Bean
fun jwtDecoder() : JwtDecoder {
return NimbusJwtDecoder.withPublicKey(this.key).build();
}
}
Either the Boot property or the JwtDecoder #Bean will introduce a filter automatically into the filter chain called BearerTokenAuthenticationFilter, so you don't need to create your own.

Spring security configuration does not apply with Spring SimpleUrlHandlerMapping

I am writing a spring boot application in which I am registering a URL to a bean via the SimpleUrlHandlerMapping configuration. Why am I not using the #Controller or #RequestMapping classes to do this ?!! Because I want to dynamically register URL's during runtime.
I am using the following code to register a simple URL to a controller
#Bean
public SimpleUrlHandlerMapping sampleServletMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Integer.MAX_VALUE - 2);
Properties urlProperties = new Properties();
urlProperties.put("/index", "myController");
mapping.setMappings(urlProperties);
return mapping;
}
The above code is working fine, I am able to hit the controller bean registered with the name "myController".
The issue appears when I use spring security. I introduced spring security and configured InMemoryAuthentication, and set my configuration as follows.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/index").permitAll()
.anyRequest()
.permitAll();
}
After doing this when I try to access /index path, it throws a 403, forbidden error. I have tried with permitAll() and fullyAuthenticated() configurations. It doesn't seem to work. However, any Controller class registered with the #Controller and #RequestMapping annotations are perfectly working fine with Security.
So, my assumption is that Spring Security is not aware of the dynamically registered URL's via the SimpleUrlHandlerMapping.
How do I solve this ? Is there a way I can tell spring security to include my dynamic URL registrations ? Unable to find any article on this online.
Suggestions and help much appreciated.
UPDATE:
Why csrf().disable() does works
CSRF stands for Cross Site Request Forgery
In simple words, it is one kind of token that is sent with the request to prevent the attacks. In order to use the Spring Security CSRF protection, we'll first need to make sure we use the proper HTTP methods for anything that modifies the state (PATCH, POST, PUT, and DELETE – not GET).
CSRF protection with Spring CookieCsrfTokenRepository works as follows:
The client makes a GET request to Server (Spring Boot Backend), e.g. request for the main page
Spring sends the response for GET request along with Set-cookie header which contains securely generated XSRF Token
The browser sets the cookie with XSRF Token
While sending a state-changing request (e.g. POST) the client (might be angular) copies the cookie value to the HTTP request header
The request is sent with both header and cookie (browser attaches the cookie automatically)
Spring compares the header and the cookie values, if they are the same the request is accepted, otherwise, 403 is returned to the client
The method withHttpOnlyFalse allows angular to read XSRF cookie. Make sure that Angular makes XHR request with withCreddentials flag set to true.
For more details, you may explore the following
Will Spring Security CSRF Token Repository Cookies Work for all Ajax Requests Automatically?
AJAX request with Spring Security gives 403 Forbidden
Basic CSRF Attack Simulation & Protection with Spring Security
Updated method configure(HttpSecurity http)
http
.csrf()
.ignoringAntMatchers("endpoint-to-be-ignored-for-csrf")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()
.antMatchers("/index").permitAll()
.anyRequest().authenticated();
Endpoint specified in antMatchers with permitAll() should not required authentication and antMatchers("/index").permitAll() should work fine.
Make sure your security configuration class is annotated with #EnableWebSecurity and #EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
The security configuration class is in follows the package structure and scanned by Spring. spring-component-scanning
You may find the minimal working example here
SecurityConfiguration.java
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// https://stackoverflow.com/a/56389047/10961238 -> WebSecurity vs HttpSecurity
// Add this method if .antMatchers("/index").permitAll() does not work
#Override
public void configure(WebSecurity web) throws Exception {
web.debug(true);
// web
// .ignoring()
// .antMatchers("/index");
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/index").permitAll() //commenting this line will be results in 403
.anyRequest().authenticated();
}
}
SampleController.java
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#Controller("myController")
public class SampleController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("::::::::::::::::::::::::::::::::Controller:::::::::::::::::::::::::::::::::");
response.getWriter().print("Hello world!");
return null;
}
}
MainApplication.java
import com.example.mappings.controller.SampleController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import java.util.Properties;
#SpringBootApplication
public class MappingsApplication {
public static void main(String[] args) {
SpringApplication.run(MappingsApplication.class, args);
}
#Bean
public SimpleUrlHandlerMapping sampleServletMapping() {
System.out.println("::::::::::::::::::::::::::::::::SimpleUrlHandlerMapping:::::::::::::::::::::::::::::::::");
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Integer.MAX_VALUE - 2);
Properties urlProperties = new Properties();
urlProperties.put("/index", sampleController());
mapping.setMappings(urlProperties);
return mapping;
}
#Bean
public SampleController sampleController() {
System.out.println("::::::::::::::::::::::::::::::::Setting SampleController:::::::::::::::::::::::::::::::::");
return new SampleController();
}
}
application.properties
spring.security.user.name = user
spring.security.user.password = user
spring.security.user.roles = ADMIN

Resources