我试图让我的春天安全性为春季启动,我在网上找到的所有信息都与Spring启动MVC示例有关,其中创建了login.html页面等。我需要的是一个带有用户名和密码的普通旧HTTP GET /登录页面。
我目前为WebSecurityConfig所拥有的是:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsService userDetailsService;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.authorizeRequests().antMatchers("/login/**").permitAll()
.anyRequest().authenticated().and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).deleteCookies().and()
.csrf().disable();
}
@Bean(name="passwordEncoder")
public PasswordEncoder passwordencoder (){
return new BCryptPasswordEncoder();
}
}
我的AuthenticationProviderConfig
@Configuration
public class AuthenticationProviderConfig {
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
AgentRepository agentRepository;
@Bean(name="userDetailsService")
public UserDetailsService userDetailsService(){
JdbcDaoImpl jdbcImpl = new JdbcDaoImpl();
jdbcImpl.setDataSource(jdbcTemplate.getDataSource());
jdbcImpl.setUsersByUsernameQuery("select username,password, enabled from agent where username=?");
jdbcImpl.setAuthoritiesByUsernameQuery("select b.username, a.role from agent_role a, agent b where b.username=? and a.agent_role_id=b.id");
return jdbcImpl;
}
}
这种方法很好,但对我的项目来说并不理想。 现在,每当我的服务器上的任何URL的请求进入时,将通过服务器领域向用户询问用户名和密码。在前端应用程序术语中,这意味着开发人员需要为他们发送到服务器的每个请求提供基本身份验证标头。
有没有办法自定义登录,以便它通过这样的POST请求:
@Autowired
UserDetailsService userDetailsService;
@RequestMapping(value = "login", method = RequestMethod.POST)
public void login(String username, String password){
userDetailsService.loadUserByUsername(username);
//somehow login and create session?
}
答案 0 :(得分:0)
我使用以下解决方案,它的工作原理。 制作一个控制器:
@RequestMapping(value = "/login", method = RequestMethod.POST)
public SecurityUserResource login(@RequestParam("name") String name,@RequestParam("password") String password){
SystemUserJpa userJpa = userService.login(name, password);
return assembler.toResource(userJpa);
}
并且在SystemUserService中如下所示:
@Service
@Transactional
public class SystemUserService {
@Autowired SystemUserRepository userRepo;
@Autowired SystemUserDetailsService userService;
@Autowired PasswordEncoder passwordEncoder;
@Autowired ResourceLoader loader;
@Autowired(required=false) SessionService sessionService;
/**
* @param name
* @param password
* @return
*/
public SystemUserJpa login(String name,String password){
// build authentication token for user
SystemUserJpa userJpa = userRepo.findByNameLikeIgnoreCase(name);
if (userJpa==null) {
throw new AuthenticationFailedException("login failed");
}
if (!passwordEncoder.matches(password, userJpa.getEncryptedPassword())) {
throw new AuthenticationFailedException("login failed");
}
UserDetails user = userService.loadUserByUsername(name);
final Authentication auth = new UsernamePasswordAuthenticationToken(name, password,user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
if (sessionService!=null) {
sessionService.login(userJpa);
}
return userJpa;
}
} 重要的是 。SecurityContextHolder.getContext()setAuthentication(AUTH); 在此之后,用户经过身份验证,并在会话中进行测试。当来自该用户的下一个请求到达时,使用相同的会话,并且由于其经过身份验证,他可以访问需要身份验证的页面,而不会再次要求输入密码。