So I'm new to Spring, and learning in the way as I develop a web application using Spring-Boot.
Currently my page consists of two html pages: index.html and login.html. I'm also using Spring-Security.
Here's my current MvcConfig:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/login").setViewName("login");
}
}
The way the website is designed, an user goes to the url http://localhost:8080, then he/she is presented with the initial page, there's a login tab there where he/she can log in, and move to the dashboard view (which I will add later).
However, when I load the initial, the page is totally misconfigured (css / js / images resources aren't loaded). After I go to http://localhost:8080/login, perform the login and everything works again.
Therefore, any url of the form http://localhost:8080 is to be allowed (index.html), but anything else would require login.
Here's my Spring-Security config:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.regexMatchers("/", "/index").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
How can I correctly configure my webpage?
*** Notes:
* I currently don't have any Controller class.
problem with regex matchers that i found is any resource loaded from your server you will need to account for in the mapping.
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/admin").hasRole('ADMIN') // e.g. for pages that need to be authenticated
.anyRequest().permitAll() // all the others will be accessable by all
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
The most simplest way to do matching is following steps:
Declare your resource files by overriding addResourceHandlers
Use antmatchers to handle url security (simpler and easier), unless you have extremely dynamic urls with critical parameter
sorry guy, I will try to make it clear
anyRequest().authenticated() make your request to html resource need to authorized. You only permitAll to '/' & '/login'
so, add permitAll to css, js, image too
http
.authorizeRequests()
.regexMatchers("/", "/index").permitAll()
.antMatchers("/**/*.js", "/**/*.css").permitAll()
or more easy, make a style for login page. no depend on other static resource.
Related
I'm trying to add spring security to a custom Java project, by manually adding all dependencies etc. So far I've been successful, but I (think I) have a problem with my WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers("/index.html").hasAnyRole("USER", "ADMIN")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.formLogin()
.loginPage("/sign-in")
.permitAll();
}
When restricting index.html as above, the user is immediately required to login when entering the application base-URL (e.g localhost:8080/myapp/). However if I change the antMatcher to:
...
http.authorizeRequests()
.antMatchers("/test**").hasAnyRole("USER", "ADMIN")
.and()
...
I can hit the application base-URL without having to login. It's worth mentioning that index.html and test.html are completely identical (they only contain an h1-tag), and are both located in the root of the generated .war-file:
enter image description here
How do I configure the application so that the user doesn't have to login when entering the base-url, but only when requesting the index.html (e.g. localhost:8080/myapp/index.html)?
Thanks in advance
Edit: My app has an endpoint at localhost:8080/myapp/ looking like this:
#GetMapping("/")
public String home() {
return ("<h1>Welcome</h1>");
}
The idea is that the user should be able to reach this without having to authenticate.
You can try this...
'''
http.authorizeRequests()
.antMatchers("/test**").permitAll().antMatchers("/index.html").hasAnyRole("USER", "ADMIN")
.and()
'''
if test.html is your base file.
I am trying to understand this spring-boot project:hbs-spring-boot-jpa-mysql-thymeleaf-security
In the HbsController the code is
As I know when I input the localhost:8080/hbs, I should see the index page right? but I can only see thisAnd I look into the project I can't find the login page? where is it? please help me.
in the SecurityConfig you might have the /hbs mapping with authorisation required.
in this example from https://www.baeldung.com/spring-security-login
#Override
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/perform_login")
.defaultSuccessUrl("/homepage.html", true)
//.failureUrl("/login.html?error=true")
.failureHandler(authenticationFailureHandler())
.and()
.logout()
.logoutUrl("/perform_logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler());
}
".antMatchers("/admin/**").hasRole("ADMIN")" forces the acces to only "ADMIN" users and redirects them to /login
try to modify your configuration class that implements WebSecurityConfigurerAdapter and it will work
I think it is because there is spring boot security implemented/included in the pom file/project: https://spring.io/guides/gs/securing-web/
You can see the spring security configuration in the class "SpringSecurity.java" in the folder "security". You can modify it there or look up what the credentials are.
I have troubles with Spring Security. I want to override the built-in /login endpoint from spring in order to be able to load mylogin.html page which is located under resources/templates/mylogin.html. I think that this issue comes from the below code. Also, the class is annotated with #EnableWebSecurity.
The security bean configuration from my project:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
//The pages does not require login
http.authorizeRequests().antMatchers("/","/welcome","logout").permitAll();
// /userInfo page requires login as ROLE_ADMIN, ROLE_DOCTOR, ROLE_PATIENT
http.authorizeRequests().antMatchers("/userInfo").access("hasAnyRole('ROLE_ADMIN','ROLE_DOCTOR','ROLE_PATIENT')");
//For ADMIN only
http.authorizeRequests().antMatchers("/admin").access("hasRole('ROLE_ADMIN')");
http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/403");
//Config for Login Form
http.authorizeRequests().anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/mylogin.html")
.permitAll(true)
.and()
.logout()
.logoutSuccessUrl("/mylogin.html?logout")
.permitAll();code here
}
Is someone who can help me?
I advise you to use spring-boot-starter-thymeleaf library. You can do
.loginPage("/login")
Then with Spring Controller, you can catch the /login request in a method. In this method, return "mylogin" will redirect user to the mylogin.html page.
Example here: https://github.com/cihangir-mercan/spring-boot/
I'm working with Spring Boot 1.4.2.RELEASE, Spring Security 4.1.3.RELEASE, and Java 8.
For the security configuration I have the following class:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/assets/**", "/logout", "/login");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement() // 1
.sessionFixation() // 2
.migrateSession() // 3
.maximumSessions(1) // 4
.maxSessionsPreventsLogin(true).expiredUrl("/login").and() // 5
.invalidSessionUrl("/login") // 6
.and() // 7
.authorizeRequests()
.antMatchers("/app/**").authenticated()
.antMatchers("/about").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/auth").permitAll()
.defaultSuccessUrl("/app/index", true)
.failureUrl("/login?error")
.usernameParameter("uid")
.passwordParameter("pwd").and()
.logout()
.permitAll()
.invalidateHttpSession(true)
.logoutUrl("/logout").permitAll()
.logoutSuccessUrl("/login").permitAll()
.clearAuthentication(true).and()
.exceptionHandling().and()
.csrf().disable()
.headers().frameOptions().disable()
.cacheControl().and();
}
}
When try access to "/about" (permit all everyone), redirects me to "/login". I try it a second time and now it allows me to access "/about".
I have changed the authorization order of requests in the configuration class but don't works. When I delete the lines of sessionManagement (1 to 7), everything works normally.
Do I need any extra configuration?
When you are testing this, did you clear your browser's cookie with regard to your testing site? The session management filter sets a jsessionid cookie, which gets sent back. Your browser has no idea that you reset your server, so thinks the cookie is just fine, and you send back an invalid session.
You may want to take a look at your session creation policies to see whether or not it suits your purpose.
I have below configuration class where I would like to authorize certain requests and deny all others.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/phx-config-rest/dev/master").hasRole("DEV")
.anyRequest().authenticated()
.and()
.csrf()
.disable();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.
inMemoryAuthentication()
.withUser("devuser")
.password("dev")
.roles("DEV");
}
}
As per this code my impression was, Spring will only allow me to access /phx-config-rest/dev/master using the user 'devuser' and If I try access /phx-config-rest/prod/master or any other url, request would considered as un-authorized access. BTW, this code piece is regarding Spring cloud config server. Any thought?
change the
.anyRequest().authenticated()
to
.anyRequest().denyAll()
You restrict only URL /phx-config-rest/dev/master to users with role DEV, but all other URLs are accessible for every logged in user (including user devuser) with any role,
see ExpressionUrlAuthorizationConfigurer.AuthorizedUrl#authenticated:
Specify that URLs are allowed by any authenticated user.
You have to use ExpressionUrlAuthorizationConfigurer.AuthorizedUrl#denyAll instead of authenticated:
Specify that URLs are not allowed by anyone.