//我的Controller类的一部分
@RequestMapping("/login")
public String login(HttpServletRequest request,HttpServletResponse response) {
request.setAttribute("mode", "MODE_LOGIN");
return "welcomepage";
}
@RequestMapping ("/login-user")
public String loginUser(@ModelAttribute User user, HttpServletRequest request,HttpServletResponse response) {
if((userService.findByUsernameAndPassword(user.getUsername(), user.getPassword())!=null)) {
Cookie loginCookie=new Cookie("mouni","user.getUsername()");
loginCookie.setMaxAge(30*5);
response.addCookie(loginCookie);
return "homepage";
}
else {
request.setAttribute("error", "Invalid Username or Password");
request.setAttribute("mode", "MODE_LOGIN");
return "welcomepage";
}
}
我正在用Java Spring Boot做一个库管理项目。 我有一个问题,我想使用Cookie进行身份验证。 简而言之,在用户使用其凭据登录后,用户名应另存为cookie值。下次用户登录时,只需输入用户名即可成功登录。 有人可以帮我吗
答案 0 :(得分:1)
由于安全性很复杂,因此即使您的任务是不这样做,我还是建议使用Spring Security。为了说明安全性的复杂性,我已经告诉您您当前的代码具有漏洞,因为您信任纯文本用户名密码作为唯一的身份验证。另一方面,Spring Security使用密钥来生成一个“记住我” cookie,因此假冒他人(除非您知道密钥)要困难得多。
因此,如果您要使用Spring Security,那么您要做的第一件事就是创建一个UserDetailsService
,它具有一个称为loadByUsername()
的方法。要实现这一点,您可以使用UserService
并使用User
构建器来构造Spring Security用户对象:
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if ("admin".equalsIgnoreCase(username)) {
return User.builder()
.username(username)
// This should contain the hashed password for the requested user
.password("$2a$10$T5viXrOTIkraRe2mZPyZH.MAqKaR6x38L.rbmRp53yQ8R/cFrJkda")
// If you don't need roles, just provide a default one, eg. "USER"
.roles("USER", "ADMIN")
.build();
} else {
// Throw this exception if the user was not found
throw new UsernameNotFoundException("User not found");
}
}
请注意,与您原来的UserService.findByUsernameAndPassword()
相反,您不必自己检查密码,只需检索用户对象并传递哈希密码即可。
下一步是提供适当的PasswordEncoder
bean。在我的示例中,我使用BCrypt旋转10次,因此创建了以下bean:
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}
@Bean
public UserDetailsService userDetailsService() {
return new MyUserDetailsService();
}
}
下一步是配置Spring Security。例如:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.html").permitAll()
.loginProcessingUrl("/login-user").permitAll().usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("/welcome.html")
.and()
.rememberMe()
.alwaysRemember(true)
.tokenValiditySeconds(30*5)
.rememberMeCookieName("mouni")
.key("somesecret")
.and()
.csrf().disable();
}
在这种情况下,所有端点(/**
)都将得到保护,您将在login.html
拥有一个登录表单,其中包含两个表单字段(username
和password
) 。表单的目的地应为/login-user
,当用户成功登录后,他将被重定向到/welcome.html
。
类似于您在代码中编写的内容,这将生成一个名为mouni
的cookie,其中包含一个值(不再是纯用户名),并且有效期为150秒,就像您的示例一样。>
我在这里禁用CSRF,因为我使用的是简单的HTML表单,否则我将不得不添加一个模板引擎来传递CSRF密钥。理想情况下,应启用此功能。
答案 1 :(得分:0)
您正在使用Spring框架,该框架具有您要实现的功能。那为什么要手动做呢?
看看Spring安全性。
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/