我遇到了一些实现spring安全性的问题,特别是USER和ADMIN。我希望每种角色类型都重定向到其各自的页面/用户和/ admin。我已经阅读了无数的教程,每个教程似乎与最后一个教程有点不同,这一切都非常令人困惑。我想知道是否有人可以定义我需要做什么,因为我不认为我对目前为止所做的事情太过分了。目前的问题是它没有按照说法重定向,我不认为它正在创建一个会话,因为当我尝试在登录后检索任何Prinicipal.getName()时它始终为null。除此之外我还有什么我想念的吗?非常感谢任何帮助。
几乎整个应用程序都禁止注册功能,userRepo和views。
公共类UserDetailService实现UserDetailsService {
@Autowired
UserRepo userRepo;
public UserDetailService(UserRepo userRepo){
this.userRepo=userRepo;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//Find a user by username
User user = this.userRepo.findByUsername(username);
//Check if it's null
if(user == null) throw new UsernameNotFoundException(username);
//if not then return user detail with arguments
else return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), getAuthorities(user));
}
@SuppressWarnings("serial")
public static Collection<GrantedAuthority> getAuthorities(User user) {
// make everyone ROLE_USER
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
GrantedAuthority grantedAuthority = new GrantedAuthority() {
@Override
public String getAuthority() {
if (user.getRole().equals("ROLE_USER")) return "ROLE_USER";
else return "ROLE_ADMIN";
}
};
grantedAuthorities.add(grantedAuthority);
grantedAuthority = new GrantedAuthority() {
@Override
public String getAuthority() {
return "ROLE_USER";
}
};
grantedAuthorities.add(grantedAuthority);
return grantedAuthorities;
}
@服务 公共类UserServices {
@Autowired
private UserRepo userRepo;
//User register service
public void register(User user) {
//Encrypt password
user.setPassword(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()));
user.setRole("ROLE_USER");
this.userRepo.save(user);
}
//Used to add admin accounts on boot
public void adminOnBoot(User user) {
user.setPassword(BCrypt.hashpw(user.getPassword(), BCrypt.gensalt()));
this.userRepo.save(user);
}
//Return the list of users available
public List<User> getAllUsers() {
return this.userRepo.findAll();
}
//Check if user exists by a username
public Boolean existsByUsername(String username) {
return this.userRepo.existsByUsername(username);
}
//Check if user exists by an email
public Boolean existsByEmail(String emailAddress) {
return this.userRepo.existsByEmail(emailAddress);
}
//Login user by the login forms username and password
public User loginUserByForm(LoginForm loginForm) {
User user = this.userRepo.findByUsername(loginForm.getUsername());
if(user != null && BCrypt.checkpw(loginForm.getPassword(), user.getPassword()))
return user;
else return null;
}
@Controller 公共类LoginController {
@Autowired
private UserServices userService;
//LOGIN PROCESS - NO NEED FOR SEPERATE VIEW
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String verifyLogin(@Valid @ModelAttribute("loginForm") LoginForm loginForm, Model model, HttpServletRequest request) {
User user = userService.loginUserByForm(loginForm);
if(user == null) {
//Add a model attribute for an error
model.addAttribute("loginError", "notNull");
//Passing the no. of registered users
model.addAttribute("users", userService.getAllUsers());
model.addAttribute("userCount", userService.getAllUsers().size());
return "index";
}
//create the HttpSession
request.getSession().setAttribute("user", user);
//Passing the no. of registered users
model.addAttribute("users", userService.getAllUsers());
model.addAttribute("userCount", userService.getAllUsers().size());
model.addAttribute("username", user.getUsername());
//TO DO
return "admin";
}
@RequestMapping("/logout")
public String verifyLogout(HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login?logout";
}
}
@Configuration @EnableWebSecurity 公共类SpringSecurityConfigurer扩展了WebSecurityConfigurerAdapter {
@Autowired
private UserRepo userRepo;
@Autowired
private CustomAuthenticationHandler authHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsServiceBean());
}
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return new UserDetailService(userRepo);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//CSS FILES AND IMAGES
.antMatchers("/css/**", "/img/**", "/js/**").permitAll()
//PAGES FOR ALL PEOPLE
.antMatchers("/", "/login", "/register/**").permitAll()
//PAGES FOR ADMIN
.antMatchers("/admin/**").hasAuthority("ADMIN")
//PAGES FOR USERS
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.loginPage("/")
.failureUrl("/?error")
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/");
;
}
}
公共类CustomAuthenticationHandler实现AuthenticationSuccessHandler {
@Autowired
UserRepo userRepo;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
HttpSession session = request.getSession();
User user = userRepo.findByUsername(authentication.getName());
session.setAttribute("user", user);
response.setStatus(HttpServletResponse.SC_OK);
if (user.getRole().equals("ROLE_ADMIN")) {
response.sendRedirect("/admin/");
} else {
response.sendRedirect("/user/" + user.getUsername());
}
}
}
答案 0 :(得分:0)
问题在于您的角色定义:
WebSecurityConfiration您正在唱歌 ADMIN
.antMatchers("/admin/**").hasAuthority("ADMIN")
但您正在寻找ROLE_ADMIN重定向到/ admin
user.getRole().equals("ROLE_ADMIN")
与USER相同,您正在寻找 USER ,但您已定义 ROLE_USER
此致
答案 1 :(得分:-1)
经过几个小时,我终于成功了。对于任何有类似自定义登录表单问题的人(不是j_spring_security_check ..)我设置了一个新的 CustomAuthenticationProvider.java
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
User user = userRepo.findByUsername(authentication.getName());
String name = authentication.getName();
String password = authentication.getCredentials().toString();
if(user != null) return new UsernamePasswordAuthenticationToken(name, password, getAuthorities(user));
return null;
}
我认为将其添加到安全配置中如下...
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(cap);
}
简单的解决方法确实令人困惑,因为有太多不同的信息。 问候, 本