How to use SpringSecurity and JDBI - java

I'm trying to configure a server with Spring. I want to use Spring security and JDBI at the same time.
So I've configured the datasource of my server (?) and linked it to JDBI. But I'm not able to use this datasource in the WebSecurityConfig.
This is my Main config java file :
#SpringBootApplication
#EnableAutoConfiguration
public class Application extends WebMvcConfigurerAdapter {
private static DBI dbi = null;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
static DBI getDbi() {
if(dbi == null) {
DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test", "ndl", "ndl");
dbi = new DBI(ds);
}
return dbi;
}
}
This is the file for security spring
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()
.logout()
.permitAll();
http.csrf().disable();
}
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery(
"select username,password from users where username=?")
.authoritiesByUsernameQuery(
"select username, role from users where username=?");
}
}
I got this error.
Field dataSource in rest.WebSecurityConfig required a bean of type 'javax.sql.DataSource' that could not be found.
I tried to write the DataSource ds in the class (and not in the method). And add to it the annotation #Bean. But i got an other error
public static DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test", "ndl", "ndl");
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public static DataSource getDataSource(){
return ds;
}
And the error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/core/support/JdbcDaoSupport
I hope you have any ideas...
Thanks ;)

Problem found.
I missed the following dependency : spring-jdbc
So my final build.gradle is
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-rest-service'
version = '0.1.0'
}
repositories {
mavenCentral()
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile('org.springframework.boot:spring-boot-starter-test')
compile("org.springframework.boot:spring-boot-starter-security")
testCompile("org.springframework.security:spring-security-test")
compile group: 'org.jdbi', name: 'jdbi', version: '2.4.2'
compile group: 'com.h2database', name: 'h2', version: '1.3.148'
compile group: 'org.springframework', name: 'spring-jdbc', version: '4.3.8.RELEASE'
}

Related

Spring Boot Keycloak Adapter cannot authorize requests to context url "/"

I have a simple Spring Boot (2.4.5-SNAPSHOT) web project using keycloak-spring-boot-starter (12.0.4) adapter for Keycloak integration. I can secure all the endpoints except the context/base url of the application. The requests coming to this base url are not authenticated. Do I make a mistake in the configure method?
http://localhost:3000/greetings is secure, redirects to Keycloak login. But http://localhost:3000 is insecure.
HelloController.java
#RestController
public class HelloController {
#GetMapping("/greetings")
public ResponseEntity<String> getGreetings() {
return ResponseEntity.ok("Hello world!");
}
#GetMapping("/")
public ResponseEntity<String> getContextGreetings() {
return ResponseEntity.ok("Hello world context!");
}
}
KeycloakSecurityConfig.java
#Configuration
#EnableWebSecurity
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable()
.authorizeRequests().antMatchers("/**").authenticated();
//.authorizeRequests(authorize -> authorize.anyRequest().authenticated());
// Also tried the commented one, doesn't work either.
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
#Bean
#Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
#Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
application.properties
server.port=3000
keycloak.realm=myrealm
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.resource=my-client
keycloak.credentials.secret=b5c3154c-012b-4ce2-af14-d58505a2a54d
keycloak.use-resource-role-mappings=true
build.gradle
...
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.keycloak:keycloak-spring-boot-starter:12.0.4'
implementation 'org.keycloak.bom:keycloak-adapter-bom:12.0.4'
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.2'
}
Found the reason thanks to the following SO answer.
In the configure method, super.configure(http); is being called. The parent configure method makes the logout url insecure which makes sense since it's the redirection page after the logout. In order overcome this issue, the logoutSuccessUrl needs to be set to another url.
See the last line of the method from KeycloakWebSecurityConfigurerAdapter:
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
.and()
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), LogoutFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/"); //permits the path
}

Spring Boot Admin - Basic Auth

I'm setting up basic auth in my sb-admin and client, but the client can't register (401 unauthorized). Everything works without auth.
SB-Admin configuration:
application.properties
server.port=8080
spring.application.name=SB Admin
spring.boot.admin.ui.title=SB Admin
spring.security.user.name=admin
spring.security.user.password=admin
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'de.codecentric:spring-boot-admin-starter-server'
Client configuration:
application.properties
server.port=9000
management.endpoints.web.exposure.include=*
management.security.enabled=false
spring.boot.admin.client.enabled=true
spring.boot.admin.client.url=http://localhost:8080
spring.boot.admin.client.username=admin
spring.boot.admin.client.password=admin
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'de.codecentric:spring-boot-admin-starter-client'
Security Config
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
private final AdminServerProperties adminServer;
public SecurityConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
this.adminServer = adminServerProperties;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeRequests((authorizeRequests) -> authorizeRequests.antMatchers(this.adminServer.path("/assets/**"))
.permitAll().antMatchers(this.adminServer.path("/login")).permitAll().anyRequest().authenticated())
.formLogin((formLogin) -> formLogin.loginPage(this.adminServer.path("/login"))
.successHandler(successHandler).and())
.logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout")))
.httpBasic(Customizer.withDefaults())
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminServer.path("/instances"),
HttpMethod.POST.toString()),
new AntPathRequestMatcher(this.adminServer.path("/instances/*"),
HttpMethod.DELETE.toString()),
new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))))
.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("USER");
}
}
Does anybody can help me please?
It's not enough just to add the spring security starter. You have to add a configuration class annotated with #EnableWebSecurity. Typically it'd be something like the following class, where you could configure things that are related to security of your app.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/index").permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
Make sure you are adding these lines in client properties file.
these credential will be submitted by admin server at the time of registration
spring.boot.admin.client.instance.metadata.user.name=client_username
spring.boot.admin.client.instance.metadata.user.password=client_password
#Marcos Vidolin All of your code snippets are correct, simply update configure method body in SecurityConfig with:
auth
.inMemoryAuthentication()
.withUser("admin")
.password("{noop}admin")
.roles("ADMIN");
It will fix the login error.

Spring boot oauth2: No userInfo endpoint - How to load the authentication (Principal) from the JWT access token directly in the client

I am setting up an oauth 2.0 client application which will redirect the users to an external IDP (Authorization Server) to sign in. My app will undergo the regular oauth 2 Authorization code grant flow - 1)Redirect the users to sign in. 2)Obtain the access code first 3) Use the access code to obtain the token. Since the external IDP is using oauth 2 just for authentication, they are not going to provide a user-info endpoint url (required by an OIDC provider) to get the user details. Instead they want us to get the claims from the JWT token directly and make any authorizations in our app.
I am unable to find the right code/configuration which will not expect a user-info endpoint and instead decode the jwt directly for loading the authentication.
In the below demo code, if I were to decode the user details from the JWT token issued by OKTA without calling its userInfo endpoint, how do I do that?
I am using spring boot 2.x release using the standard oauth client configuration provided in the spring reference sample social oauth2 projects.
I would really appreciate if someone could guide me in the right path. Thank you!
gradle configuration
buildscript {
ext {
springBootVersion = '2.2.0.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
configurations {
compile.exclude module: 'spring-boot-starter-logging'
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-log4j2:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
compile("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:${springBootVersion}")
compile("org.webjars:jquery:2.1.1")
compile("org.webjars:bootstrap:3.2.0")
compile("org.webjars:webjars-locator-core:0.42")
}
application.yml
github:
client:
clientId: <clientId>
clientSecret: <clientSecret>
accessTokenUri: https://github.com/login/oauth/access_token
userAuthorizationUri: https://github.com/login/oauth/authorize
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
resource:
userInfoUri: https://api.github.com/user
okta:
client:
clientId: <clientId>
clientSecret: <clientSecret>
accessTokenUri: https://<okta-sub-domain>/oauth2/default/v1/token
userAuthorizationUri: https://<okta-sub-domain>/oauth2/default/v1/authorize
scope: openid profile email
resource:
userInfoUri: https://<okta-sub-domain>/oauth2/default/v1/userinfo
OAuth2Config.java
#Configuration
#EnableOAuth2Client
public class Oauth2Config extends WebSecurityConfigurerAdapter {
#Autowired
OAuth2ClientContext oauth2ClientContext;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**", "/error**")
.permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);;
http.csrf().disable();
}
private Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List<Filter> filters = new ArrayList<>();
OAuth2ClientAuthenticationProcessingFilter githubFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
OAuth2RestTemplate githubTemplate = new OAuth2RestTemplate(github(), oauth2ClientContext);
githubFilter.setRestTemplate(githubTemplate);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), github().getClientId());
tokenServices.setRestTemplate(githubTemplate);
githubFilter.setTokenServices(tokenServices);
filters.add(githubFilter);
OAuth2ClientAuthenticationProcessingFilter oktaFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/okta");
OAuth2RestTemplate oktaTemplate = new OAuth2RestTemplate(okta(), oauth2ClientContext);
oktaFilter.setRestTemplate(oktaTemplate);
tokenServices = new UserInfoTokenServices(oktaResource().getUserInfoUri(), okta().getClientId());
tokenServices.setRestTemplate(oktaTemplate);
oktaFilter.setTokenServices(tokenServices);
filters.add(oktaFilter);
filter.setFilters(filters);
return filter;
}
//Client registration
#Bean
#ConfigurationProperties("github.client")
public AuthorizationCodeResourceDetails github() {
return new AuthorizationCodeResourceDetails();
}
//user info endpoints
#Bean
#ConfigurationProperties("github.resource")
public ResourceServerProperties githubResource() {
return new ResourceServerProperties();
}
#Bean
#ConfigurationProperties("okta.client")
public AuthorizationCodeResourceDetails okta() {
return new AuthorizationCodeResourceDetails();
}
#Bean
#ConfigurationProperties("okta.resource")
public ResourceServerProperties oktaResource() {
return new ResourceServerProperties();
}
//For Handling Redirects
#Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
}
A simple controller with an endpoint used by html page
#RestController
public class UserController {
#GetMapping("/user")
public Principal user(Principal principal) {
return principal;
}
}
#SpringBootApplication
public class Oauth2Application {
public static void main(String[] args) {
SpringApplication.run(Oauth2Application.class, args);
}
}
DefaultReactiveOAuth2UserService looks up the userInfo. We can simply introduce a new ReactiveOAuth2UserService implementation to take values from the token, e.g.:
#Service
public class GttOAuth2UserService implements ReactiveOAuth2UserService<OAuth2UserRequest, OAuth2User> {
#Override
public Mono<OAuth2User> loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
final List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("authority"));
final Map<String, Object> attributes = oAuth2UserRequest.getAdditionalParameters();
final OAuth2User user = new DefaultOAuth2User(authorities, attributes, "email");
return Mono.just(user);
}
}
(in your case it may be the non-reactive equivalents)

Getting a 404 when trying to load index.jsp using Spring MVC

Even after checking other answers and comparing the code with other applications that I have developed, I can't get to load index.jsp properly. I'm working with Spring MVC, using annotations. The thing is that I have done the same before and it has worked, what could my error be this time?
MvcConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "tool.controller" })
public class MvcConfig extends WebMvcConfigurerAdapter {
private static final String VIEW_CONTROLLER = "/index.htm";
private static final String VIEW_NAME = "/view/index.jsp";
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController(VIEW_CONTROLLER).setViewName(VIEW_NAME);
}
#Override
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
WebInitializer:
public class WebInitializer implements WebApplicationInitializer {
#Override
public void onStartup(final ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(BasicConfig.class, MvcConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
ServletRegistration.Dynamic dispatcher;
dispatcher = servletContext.addServlet("dispatcher",
new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
IndexController:
#Controller
public class IndexController {
private static final String INDEX_VIEW = "/view/index.jsp";
#RequestMapping(value = { "/", "/index" })
public ModelAndView home() {
ModelAndView modelAndView = new ModelAndView(INDEX_VIEW);
return modelAndView;
}
}
Folder Structure:
Folder Structure
Console messages from Tomcat initiallization that could be relevant:
Console messages
Any help will be appreciated, thanks!
EDIT: build.gradle
apply plugin: 'base'
apply plugin:'war'
apply plugin: 'jetty'
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin:'idea'
ext.springVersion='4.1.4.RELEASE'
ext.hibernateVersion='4.3.8.Final'
ext.hibernateValidatorVersion='5.1.3.Final'
repositories {
mavenCentral()
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.10'
compile 'org.slf4j:slf4j-simple:1.7.10'
compile 'ch.qos.logback:logback-core:1.1.2'
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'org.springframework.data:spring-data-jpa:1.3.0.RELEASE'
compile "org.springframework:spring-jdbc:$springVersion"
compile "org.springframework:spring-tx:$springVersion"
compile "org.springframework:spring-orm:$springVersion"
compile "org.springframework:spring-aop:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
compile "org.springframework:spring-oxm:$springVersion"
compile "org.springframework.security:spring-security-core:4.1.3.RELEASE"
compile "org.hibernate:hibernate-entitymanager:$hibernateVersion"
compile "org.hibernate:hibernate-core:$hibernateVersion"
compile "org.hibernate:hibernate-validator:$hibernateValidatorVersion"
compile "org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final"
compile 'org.postgresql:postgresql:9.4-1201-jdbc41'
compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.1'
compile 'javax.servlet:jstl:1.2'
testCompile "org.mockito:mockito-core:1.+"
testCompile 'junit:junit:4.11'
}
eclipse {
project.natures "org.springframework.ide.eclipse.core.springnature"
}
Also try to modify your controller class according to spring's good practices.
#Controller
public class IndexController {
//private static final String INDEX_VIEW = "/view/index.jsp";
#RequestMapping(value = { "/", "/index" })
public ModelAndView home() {
ModelAndView modelAndView = new ModelAndView("index");
return modelAndView;
}
}
I have apparently found what was the problem. First of all, I'm working on Eclipse IDE. The solution that I came to was adding the folder "webapp" to the "Web Deployment Assembly" in the project's properties. After doing this, the index.jsp is loading properly and I'm not getting a 404 error anymore.

Spring Boot Security redirect after successful login - undefined

I have followed the spring boot security tutorial but the end result has an issue consisting in that after successful login the browser is redirect to /undefined.
I have even cloned the code referenced in the tutorial, thinking I have typed something wrong, or forgot to add a component or something. No, the same issue is there.
Searching on Stackoverflow I found out that you need to define the default success URL in the configure method of the WebSecurityConfigurerAdapter like so:
.defaultSuccessUrl("/")
but still no go. Accessing a protected resource leads to the login page and upon successful login I don't get redirected to the protected resource. I get to the '/undefined' page. Forcing the success works, however:
.defaultSuccessUrl("/", true)
... but this is not what I would need because after successful login the user should be redirected to secured resource (initially) requested.
Here's the relevant parts of the project:
WebSecurityConfig:
package ro.rinea.andrei.Security;
import org.springframework.beans.factory.annotation.Autowired;
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;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
Controller:
package ro.rinea.andrei.Controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class WebController {
#RequestMapping("/")
public String index() {
return "index";
}
#RequestMapping("/salut")
public String salut() {
return "salut";
}
#RequestMapping("/login")
public String login() {
return "login";
}
}
There are views defined for index, login and salut (if needed I will add their contents)
and the build.gradle file:
buildscript {
ext {
springBootVersion = '1.4.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'tstBut'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-devtools')
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('org.springframework.boot:spring-boot-starter-jersey')
compile('org.springframework.boot:spring-boot-starter-mobile')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-validation')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-web-services')
compile('org.springframework.boot:spring-boot-starter-security')
runtime('org.postgresql:postgresql')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
}
You can add a successHandler to redirect like this:
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
...
.formLogin()
.loginPage("/login")
.successHandler(new AuthenticationSuccessHandler() {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
redirectStrategy.sendRedirect(request, response, "/");
}
})
I had the same issue and this is a workaround that I used.
First have a mapping for your root "/" that is unprotected
#RequestMapping(value = { "/" }, method = RequestMethod.GET)
public ModelAndView projectBase() {
return new ModelAndView("redirect:/home");
}
Have it redirect to where you want the user to go initially like home for example
#RequestMapping(value = { "/home" }, method = RequestMethod.GET)
public ModelAndView getHome() {
ModelAndView model = new ModelAndView("account/home");
model.addObject("user", userFacade.getJsonForUser(userFacade.getUserForClient()));
return model;
}
Make sure the root url is open in your security configuration like...
http.
authorizeRequests()
.antMatchers("/").permitAll()
What will happen is now it will hit the root /, and redirect to home which is restricted and send them to the loginpage with a return url of home. it will then write correctly as /home when they first login
For some reason spring security is not respecting the default success url, and it could be a configuration issue with your web server causing it. On my local machine I don't have this issue, but on some other machines I do. The workaround works in both places, since you always end up with a returnUrl.

Categories