I just copied login/register form with spring security from web and i have huge problems. I want make all resources PUBLIC for all, because after 5 hours i totally don't know what is f****** going on with this spring security.
Ok here is my configure method 1:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// URLs matching for access rights
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/register").permitAll()
.antMatchers("/DBDesign").permitAll()
.antMatchers("/index").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest().authenticated()
.and()
// form login
.csrf().disable().formLogin()
.loginPage("/login")
.failureUrl("/login?error=true")
.successHandler(sucessHandler)
.usernameParameter("email")
.passwordParameter("password")
.and()
// logout
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
}
configuration method 2:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/static/**", "/common/**", "/js/**", "/images/**");
}
}
configuration method 3:
#Configuration
public class WebMvcConfig implements WebMvcConfigurer{
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**", "/static/**", "/templates/**")
.addResourceLocations("/webjars/", "classpath:/static/", "classpath:/templates/");
}
}
I am 100% sure that one of these methods is responsible for managing the directories that are to be available before logging in and which are not.
Guys please can someone explain how exactly this work?
Look this is my temporary file structure:
green --- i have access
red --- i dont have access
I can copy and paste path to "green" files and see what is inside, but if i am trying to do the same thing for red files... error 404. How is this possible? Only those 2x dont have permission.
The resourcehandler /static/** points to classpath:/static/
So the security-filter should ignore requests to /sidebar/**, ....
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/sidebar/**","/diagramER/**", .....);
}
Then you can use in your pages something like
<html lang="en">
<head>
....
<script src="/sidebar/js/main.js" ></script>
<script src="/diagramER/DBDesign.js" ></script>
<link rel="stylesheet" type="text/css" href="/sidebar/common/style.css">
</head>
Related
I have built an application by using Spring Boot and Thymeleaf. My application works as supposed in my localhost, but when I package it as a .war and deploy it in a test tomcat server, it prompts the login page and then either redirects me to the error page or brings me back to the login page.
I have tried multiple things, and I think that there is an issue with the way I am handling the formLogin() inside my SecurityConfig.java class. More specifically, since Tomcat adds the base-url (e.g. from localhost:8080 to serverUrl:8080/reservation) when uploading my app, the loginProcessingUrl class probably fails to identify the "/process-login" class located on the login.html page.
Please find below my SecurityConfig.java class
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private UserService userService;
private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
private AccessDeniedHandler accessDeniedHandler;
#Autowired
public SecurityConfig(UserService userService, CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler, AccessDeniedHandler accessDeniedHandler) {
this.userService = userService;
this.customAuthenticationSuccessHandler = customAuthenticationSuccessHandler;
this.accessDeniedHandler = accessDeniedHandler;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login-form-page","/resources/**").permitAll()
.antMatchers("/", "/new-reservation", "/your-reservations","/all-reservations",
"/change-password").hasAnyRole("ADMIN","EMPLOYEE","MANAGER")
.antMatchers("/users","/user-reservations","/arrival-date","/duplicate-reservations","/all-reservations","/registration**")
.hasAnyRole("ADMIN").and()
.formLogin()
.loginPage("/login-form-page")
.loginProcessingUrl("/process-login")
.successHandler(customAuthenticationSuccessHandler)
.permitAll()
.and()
.logout()
.logoutUrl("/login-form-page")
.permitAll()
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
}
#Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/resources/**", "/static/**");
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(userService);
auth.setPasswordEncoder(passwordEncoder());
return auth;
}
And here is a small sample of the login.html page.
<div class="form-container sign-in-container">
<form id="loginForm" name="regForm" th:action="#{/process-login}"
method="POST">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<h1>Sign In</h1>
<!-- Login Error -->
<div th:if="${param.error}"
class="alert alert-danger col-xs-10">Wrong email and/or password</div>
<!-- Logout notify -->
<div th:if="${param.logout}"
class="alert alert-success 1 col-xs-10">You
have been logged out.</div>
All the .html pages are located in
-resources
-templates
Lastly, the only error I see in the logs is the following
DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found
For anyone interested, I managed to solve the above issue. It seems like it was not a misconfiguration in the loginProcessingUrl() class. Instead, the issue was the way a remote server handles the JSESSIONID and csrf.
More specifically, what I had to do is
Added the following block of code in my SecurityConfig.java
cookieServerCsrfTokenRepository.setCookieHttpOnly(false);
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
Next, added the block of code below
#Bean
public ServletContextInitializer servletContextInitializer(#Value("${secure.cookie}") boolean secure) {
return new ServletContextInitializer() {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.getSessionCookieConfig().setSecure(secure);
}
};
}
The secure.cookie value needs to be set (in the application.properties to true if you intend to utilise the HTTPs protocol.
I have a Spring Boot project using Spring Security and OAuth2.0 libraries.
I confirmed when I accessed http://localhost:8080/login, the default login view is displayed and I could log in.
But if I implement Config class shown below:
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers( "/login**" ).permitAll()
.anyRequest()
.authenticated();
}
}
The browser returns "404 not found error".
I thought I could be authenticated directly accessing to a Github's API, so implemented this, but it Wouldn't work:
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(){
return "redirect:/oauth2/authorization/github";
}
How should I cope with that? I know I probably have some misunderstandings because of a lack of my knowledge,
but I only want to know how to allow access to only a login page when a user is not authenticated.
Thanks.
finally solved!
I need to append following parts to the end of the methods flow.
.and()
.oauth2Login()
.loginPage("/login");
so the final code is:
SecurityConfig.java
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login**")
.permitAll()
.anyRequest()
.authenticated()
//appended
.and()
.oauth2Login()
.loginPage("/login");
}
}
Controller.java
#GetMapping(value = "/login")
public String getit(Model model){
return "login";
}
login.html
<body>
<a th:href="#{/oauth2/authorization/github}">Login</a>
</body>
It worked!
Referenced URL:https://www.codeflow.site/ja/article/spring-security-5-oauth2-login
I'm trying to get spring security to allow the serving of static files like .css .js etc. without need to login first.
I've tried creating MVC config with resource handler and changing rules in spring security config, but nothing seems to be working.
MvcConfig.java:
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**")
.addResourceLocations("/assets/");
}
}
SecurityConfig.java:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/assets/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/assets/**");
}
}
When I go to http://localhost:8080/assets/js/particles.min.js I'm expecting it to return the file contents but every time I try links like localhost:8080/assets/* it returns the content of login.html
My assets files
My project files
Supposing that your static files are under src/main/resources:
There are two main pieces to configure:
Implement the WebMvcConfigurer interface to discover your static resources:
#Configuration
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/assets/**")) {
registry.addResourceHandler("/assets/**")
.addResourceLocations("/assets/");
}
}
}
Setup your security configuration to allow static resources (such as CSS, JavaScripts and images) to be publicly accessible:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// Your settings
#Override
protected void configure(HttpSecurity http) throws Exception {
// Your AuthN handlers and filter chain...
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/js/**").permitAll()
.anyRequest().authenticated();
// Logout handler...
}
}
Supposing that you have a CSS file as follows:
src/main/resources/assets/css/layout.css
The web server will make it accessible at:
http://<root_url>:<port>/css/layout.css
Try to change to:
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/assets/").permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
web.ignoring().antMatchers("/assets/**");
The statement above will tell spring security to Ignore any request that starts with “/assets/”. So if i were you, i will remove all the following configuration:
.antMatchers("/", "/assets/**")
.permitAll()
fom the configure(HttpSecurity http) method.
I have a simple REST application with authentication service. I tried to add swagger and swagger-ui to it, but I can only see my endpoints in /v2/api-docs.
In swagger-ui.html I see only groups of endpoints but I am unable to extend any list.
In chrome debug I see:
Failed to load resource: the server responded with a status of 401 ()
Uncaught TypeError: Cannot read property 'indexOf' of undefined
and on a terminal with a server:
ERROR 10020 --- [nio-5001-exec-3] c.t.r.a.p.JwtAuthenticationEntryPoint : Responding with unauthorized error. Message - Full authentication is required to access this resource
It looks like my config files are missing something, I tried few solutions I found on a web but still nothing work.
This is my code:
pom
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
controller
#RestController
#PreAuthorize("hasRole('USER')")
#RequestMapping(path = "restaurant")
#Api(value="restaurant", description="Example operations for restaurants")
public class RestaurantController {
// endpoints
}
swagger bean
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.tablebooker.restaurantservice.restaurant"))
.paths(PathSelectors.any())
.build();
}
}
SecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//other methods
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/restaurant/**")
.hasRole("USER")
.anyRequest()
.authenticated();
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
}
}
Any ideas how can I make my configuration work?
For me, there was no issue in traditional Weblogic deployment without any mention of #Override public void configure(WebSecurity web) throws Exception ...Only #Override protected void configure(HttpSecurity http) throws Exception was enough and UI was visible on swagger.
But the same code was not working on Apache Tomcat server so below code was needed ,
#Override public void configure(WebSecurity web) throws Exception { web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**"); // ignore swagger web.ignoring().mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs","/webjars/**"); }
/webjars/** being missing in answer by AokoQin.
Answering here because I didn't faced any issues on Weblogic without above code but only Tomcat. I already had resources added via ResourceHandlerRegistry in mvc config.
First you should registry swagger's resources.
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
}
}
Then cause you're using Spring Security,maybe you should shutdown privileges.
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**");
// ignore swagger
web.ignoring().mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs");
}
And maybe it's better for you to use swagger which the version is under 2.8.0,or you may have to face to lots of bugs.
The previous answers helped me, but are not quite complete / outdated. I was facing the same issue and it's working now:
#Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs", "/webjars/**");
}
...
}
I'm trying to add a landing page to a Spring Application that I created so that when the application initially loads the landing page is the first page that is seen. The issue is, I created the landing page after I created the application and so the application loads a login/register page first and I cannot route the landing page to open first. I'm trying to research online where I could possibly complete this task yet I'm lost and would really appreciate some help.
I've included the WebSecurityConfig file below.
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/registration").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
//Disable csrf token as it is not needed for now and is preventing the applciation from running properly
http.csrf().disable();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
}