I have a Spring 4 MVC web app which uses JPA repositories and Hibernate to map objects to a MySQL database. I have to configure Spring Security via java class. Authentication from main page works correctly and redirect me to /admin or /user pages. But I have a trouble: when i type in browser localhost:8080/admin - I go to the admin page, even if it is not to enter username and password. Please show me to my mistake in config and/or in controller
my SecurityConfig.java
@Configuration
@EnableWebSecurity
@ComponentScan("com.easygoapp.service")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("customUserDetailsService")
private UserDetailsService customUserDetailService;
//It's autowired ! Idea not correct views this!
@Autowired
private AuthenticationManagerBuilder auth;
@Autowired
AuthenticationSuccessHandler successHandler;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// CSRF protection
http.csrf()
.disable()
// requests rules
.authorizeRequests()
.antMatchers("/assets/**", "/**").permitAll()
.anyRequest().permitAll()
.and();
http.formLogin()
// login form page
.loginPage("/")
.loginProcessingUrl("/j_spring_security_check")
// URL login not success
.successHandler(successHandler)
.failureUrl("/login?error")
.usernameParameter("j_username")
.passwordParameter("j_password")
// add permissions to login page to all
.permitAll();
http.logout()
// add permissions to logout to all
.permitAll()
// logout URL
.logoutUrl("/logout")
// logout successful URL
.logoutSuccessUrl("/login?logout")
// invalidation of current session
.invalidateHttpSession(true);
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/user/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')")
.and().formLogin();
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
auth.userDetailsService(customUserDetailService);
return auth.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationSuccessHandler successHandler() {
return new CustomSuccessHandler();
}
My LoginController.java
@Controller
public class LoginController {
@Autowired
BCryptPasswordEncoder encoder;
@Autowired
UserService userService;
@RequestMapping(value = {"/", "/login"}, method = RequestMethod.GET)
public ModelAndView logged() {
ModelAndView model = new ModelAndView();
model.setViewName("index");
return model;
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {
ModelAndView model = new ModelAndView();
model.setViewName("admin");
return model;
}
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = "/user**", method = RequestMethod.GET)
public ModelAndView dbaPage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Hello World");
model.addObject("message", "This is protected page - USER Page!");
model.setViewName("message");
return model;
}
//for 403 access denied page
@RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {
ModelAndView model = new ModelAndView();
//check if user is login
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (!(auth instanceof AnonymousAuthenticationToken)) {
UserDetails userDetail = (UserDetails) auth.getPrincipal();
model.addObject("username", userDetail.getUsername());
}
model.setViewName("403");
return model;
}
My CustomUserDetailService.java
@Component("customUserDetailsService")
public class CustomUserDetailService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
//our domain entity User
User userToAuthorise = userService.getByLogin(login);
List<GrantedAuthority> authorities = buildUserAuthority(userToAuthorise.getUserRoles());
return new org.springframework.security.core.userdetails.User(userToAuthorise.getLogin(),
userToAuthorise.getPassword(), authorities);
}
private List<GrantedAuthority> buildUserAuthority(List<UserRole> userRoles) {
List<SimpleGrantedAuthority> listAuth = new ArrayList<>();
// Build user's authorities
for (UserRole userRole : userRoles) {
listAuth.add(new SimpleGrantedAuthority(userRole.getRole()));
}
return new ArrayList<GrantedAuthority>(listAuth);
}
My CustomSuccessHandler.java
public class CustomSuccessHandler implements AuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException, ServletException {
String targetUrl = getSuccessUrl(authentication);
redirectStrategy.sendRedirect(httpServletRequest, httpServletResponse, targetUrl);
clearAuthenticationAttributes(httpServletRequest);
}
private String getSuccessUrl(final Authentication authentication) {
boolean isUser = false;
boolean isAdmin = false;
final Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (final GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
isUser = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
if (isUser) {
return "/user";
} else if (isAdmin) {
return "/admin";
} else {
throw new IllegalStateException();
}
}
protected final void clearAuthenticationAttributes(final HttpServletRequest request) {
final HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
Thank for Your answers!
Aucun commentaire:
Enregistrer un commentaire