I'm completely new to Spring and MVC. I'm trying to setup https access to the specific section of my application.
I have 2 buttons: admin and user. When I press admin button, I should input login and password to enter the administration section. When I click on user button I want to pass in https zone and to get certificate from user. And I need all paths user/** to have https.
Here is my code
startPage.jsp
Admin
User
UserController.java
#RequestMapping(value = "/user", method = RequestMethod.GET)
public ModelAndView userArea(Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
if (getCertificate(request) != null) {
mv.setViewName("UserArea");
} else {
mv.setViewName("error");
}
return mv;
}
SecurityConfig.java
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMIN_ROLE')")
.antMatchers("/user/**").permitAll()
.antMatchers("/**").permitAll()
.anyRequest().authenticated();
http.formLogin()
.loginPage("/login")
.loginProcessingUrl("/j_spring_security_check")
.failureUrl("/login?error")
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll();
http.logout()
.permitAll()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true);
}
...
}
I know that now path users/** is using permitAll(), but help me, please, setup https access to this path or give me please some advice where to read some articles. And one more question, when I want to get client certificate, it contains in HttpServletRequest argument of userArea method, am I right?
This can be done using spring security as shown below.
<security:intercept-url pattern="/reports" access="ROLE_ADMIN" requires-channel="https"/>
<security:intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" requires-channel="https"/>
<security:intercept-url pattern="/**" access="ROLE_USER" requires-channel="https"/>
Below blog will give more info
http://myshittycode.com/2014/06/12/spring-security-forcing-urls-to-use-https/l
Related
I have an application providing several REST endpoints and web pages as well.
/products -- REST endpoint
/cutomers -- REST endpoint
/ui/catalog -- Web
/ui/admin -- Web
I want to set up the security so all web starting with /ui/** are redirected to a login page and all the others (REST) are challenged with 401 and WWW-Authenticate.
With the following settings the login page is not permitted and 401 with the header is sent:
#Configuration
#Order(20)
#RequiredArgsConstructor
class RestConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.requestMatcher(AnyRequestMatcher.INSTANCE)
.authorizeRequests().anyRequest().fullyAuthenticated();
httpSecurity.
requiresChannel().
requestMatchers(AnyRequestMatcher.INSTANCE).
requiresSecure();
}
}
#Configuration
#Order(10)
#RequiredArgsConstructor
class WebUIConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.antMatcher("/ui/**")
.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
Why this doesn't work? I would expect to be redirected to the login page (it works) and the login page to be 200 (it doesn't work).
Editing the WebUIConfigurationAdapter as follows solves the problem:
httpSecurity.requestMatchers()
.antMatchers("/ui/**", "/login", "/logout")
.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
The URL /login is set by WebUIConfigurationAdapter so it is then excluded by RestConfigurationAdapter.
Thanks #PraveenKumarLalasangi for his comment.
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 have a problem with Spring Security and error pages , becaus when I am logged in the application I can show when the page is not exist.
But when I am out of the application my spring security show the login page by default.
This is my spring security configuration.
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#Autowired
private DataSource dataSource;
#Value("${spring.queries.users-query}")
private String usersQuery;
#Value("${spring.queries.roles-query}")
private String rolesQuery;
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/user_login").hasAuthority("USER").anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/user_login")
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.and().exceptionHandling()
.accessDeniedPage("/access-denied");
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
}
}
This works correctly but I don't know why when I am out of the application I redirect to login page.
Any solution for this?
Regards!
All the requests other than /, /login, /registration requires the user to be authenticated (anyRequest().authenticated()), and when you are enabling formLogin() spring's filters will redirect all the not authenticated requests to the login page even if the page doesn't exits, thats is why you are redirected to the login and not getting a 404 error.
For testing purposes you can add a test matcher without adding an actual endpoint in the controller like this:
.antMatchers("/test").permitAll() and try to access this endpoint without being authenticated and you will get the 404 error page.
p.s. make sure that the 404 response is not blocked as well (if it is a controller response then enable it as well, because your js is allowed for everyone).
It looks like some filter not added.
I use Spring security 3.2.0.RELEASE with java-config.
Full project posted on GitHub
SecurityConfig.java is here: SecurityConfig.java
I try to set up filter in:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/app/**").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/")
.defaultSuccessUrl("/app/")
.failureUrl("/?error=1")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/?logout");
}
After csrf().disable() - But problem not solved...
Help me please to solve this problem for I can use /j_spring_security_check with my own CustomUserDetailsService!
I have no experience with Spring Security Java Config, but I checked your code and the API and it seems that setting login processing URL will let you login:
AbstractAuthenticationFilterConfigurer.loginProcessingUrl("/j_spring_security_check")
So your code should be:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/app/**").hasRole("ADMIN")
.and()
.formLogin()
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/")
.defaultSuccessUrl("/app/")
.failureUrl("/?error=1")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/?logout");
}
I would expect this is set by default.
In addition, to make use of MyCustomUserDetailsService, instead of autowiring it as it is now (Proxy created by Spring), I would configure it manually:
public class MyCustomUserDetailsService implements UserDetailsService {
private UserDAO userDAO;
public MyCustomUserDetailsService(UserDAO userDAO) {
this.userDAO = userDAO;
}
// ...
}
Notice, no #Service/#Component annotations and DAO injected via Ctor. In security config:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Autowired
private UserDAO userDAO;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.and()
.userDetailsService(new MyCustomUserDetailsService(userDAO));
}
// ...
}
Now I am sure, the UserDetailService is properly configured. And for sure it will be used while logging in in the application.
I also noticed that the username and password is not used. This is because in login.jsp you use j_username and j_password whereas username parameter should be username and password parameter should be password.
<input type="text" id="username" class="span4" name="username" placeholder="Username" />
<input type="password" id="password" class="span4" name="password" placeholder="Password" />
Look at the FormLoginConfigurer class.
Our app has a custom success handler for successful logins. It basically redirects them to the page they were on when their session expired.
We're moving to a Java config rather than a spring xml config. The rest of the config went very smoothly, but we can't find where to put the authentication-success-handler-ref attribute of the security:form-login tag.
<security:http auto-config='true'>
...
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
<security:form-login login-page="/login" default-target-url="/sites"
authentication-failure-url="/login"
authentication-success-handler-ref="authenticationSuccessHandler"/>
...
Here's our config, so far.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login")
.and()
.logout()
.permitAll()
.and()
}
Also, we can't find where to put default-target-url, but that is definitely less important.
Caveat, we're actually using Groovy, but the code is basically the same as a Java config.
All settings can be done inside the global configure method. Add the following:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/sites")
.failureUrl("/login")
.successHandler(yourSuccessHandlerBean) // autowired or defined below
.and()
.logout()
.permitAll()
.and()
}
You have to create bean extending SimpleUrlAuthenticationSuccessHandler or SavedRequestAwareAuthenticationSuccessHandler. For example:
#Bean
public SavedRequestAwareAuthenticationSuccessHandler successHandler() {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("/secure/");
return successHandler;
}
Then you have to setup it on bean extending AbstractAuthenticationProcessingFilter:
UsernamePasswordAuthenticationFilter authenticationFilter = new UsernamePasswordAuthenticationFilter();
authenticationFilter.setAuthenticationSuccessHandler(successHandler());