我无法以具有此角色的用户身份登录到我的应用程序 admin
或者作为角色的用户 user
. 我总是以用户身份登录 anonymous
.
Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder encoder() {
return new StandardPasswordEncoder("53cr3t");
}
@Autowired
UserDetailsServiceImpl userDetailsService;
public SecurityConfig(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/").authenticated()
.antMatchers("/rentAppPage/").hasRole("ADMIN")
.antMatchers("/addVehicle").hasRole("ADMIN")
.antMatchers("/getVehicle").hasRole("ADMIN")
.antMatchers("/removeVehicle").hasRole("ADMIN")
.antMatchers("/updateVehicle").hasRole("ADMIN")
.antMatchers("/allUser").hasRole("ADMIN")
.antMatchers("/resultGet").hasRole("ADMIN")
.antMatchers("/addUser").hasRole("ADMIN")
.antMatchers("/getUser").hasRole("ADMIN")
.antMatchers("/updateUser").hasRole("ADMIN")
.antMatchers("/removeUserById").hasRole("ADMIN")
.antMatchers("/price").hasAnyAuthority("ROLE_ADMIN", "ROLE_USER")
.antMatchers("/allScooter").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/allCar").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/allMotorBike").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/allBike").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
.antMatchers("/distance").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
.antMatchers("/user").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/rent").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/rent2").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/buy").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/buy2").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/thanks").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.antMatchers("/rentAppPage").hasAnyAuthority( "ROLE_ADMIN", "ROLE_USER")
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.and()
.logout()
.logoutSuccessUrl("/");
;
http.sessionManagement()
//.expiredUrl("/sessionExpired.html")
.invalidSessionUrl("/login.html");
}
}
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idUser;
private String username;
private String password;
private String name;
private String surname;
private String email;
private double latitude;
private double longitude;
private String role;
private String locationName;
}
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
IUserDAO userDAO;
public UserDetailsServiceImpl(IUserDAO userDAO){
this.userDAO = userDAO;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDAO.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("User dont exist");
}
return new MyUserDetails(user);
}
}
@Repository
public class UserDAOImpl implements IUserDAO {
@Autowired
SessionFactory sessionFactory;
public UserDAOImpl(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
@Override
public void addUser(User user){
Session session = null;
Transaction tx = null;
try{
session = this.sessionFactory.openSession();
tx = session.beginTransaction();
session.save(user);
tx.commit();
}catch (HibernateException e){
if(tx != null)tx.rollback();
}finally {
session.close();
}
}
@Override
public User findByUsername(String username) {
Session session = this.sessionFactory.openSession();
User user =(User) session.createQuery("FROM pl.edu.wszib.model.User WHERE username = :username" )
.setParameter("username", username)
.uniqueResult();
session.close();
return user;
}
}
public class MyUserDetails implements UserDetails {
private User user;
public MyUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(user.getRole());
return Arrays.asList(authority);
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
2021-01-18 17:05:43.545 DEBUG 4256 --- [io-8080-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@cd98cfcc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 127.0.0.1; SessionId: AD82C9600EFB66CF7C6F8A1BCCEEAE0D; Granted Authorities: ROLE_ANONYMOUS'
我在mysql数据库中有两个用户第一个角色admin第二个角色user我在数据库中的角色是role\u admin,role\u user我的完整代码在这里https://github.com/conrado1212/springsecuritywhycantworkfine 有人能解释为什么我不能以管理员或用户的身份登录应用程序吗?
2条答案
按热度按时间r6l8ljro1#
当然,关于编码器、md5等有很多问题,但这是你的选择(即使它是错的)
我运行你的代码,如果md5哈希是正确的数据库我可以登录。据我所知,问题是为什么应用程序不存储登录用户的状态?
期望值:
第一个请求:call method(incognito)->login->call method(authorized)
第x个请求:call method->spring security checks->call method(authorized)
现实:
第X个请求:始终等于第1个
原因是您没有更改spring安全上下文的状态。调用/登录端点,检查用户是否在db中,检查其密码并返回成功响应。您应该创建一个授权并将其放置在spring安全上下文中。
简单示例:
在接下来的请求中使用令牌。如何实现令牌提供者有很多例子。它可以是定制的或更好的jwt。
如果您不需要令牌(restful),可以在请求中使用会话(untinent),但它需要额外的配置。
jmp7cifd2#
查看了您在github上发布的代码,您在上述问题中发布的代码都不是问题所在。您的问题是如何执行您的登录。
登录.html
在这里,我们假设登录表单发布到端点
/authenticate
. 这不是标准/login
spring security自动为您设置的端点。因为您没有使用标准,所以我找到了您的自定义端点。
登录控制器.java
在这里,我们看到您将user对象传递到一个名为
authenticationUser
. 因此,如果我们查看该函数,就会发现这个实现。authenticationservice.java
在这个函数中,您所做的就是从数据库中获取用户。检查用户密码是否匹配,然后返回布尔值。
如果布尔值为真,则返回下一页。
这不是SpringSecurity的工作方式。上面所有的代码都是完全错误的,很明显,在这里询问堆栈溢出之前还没有做过任何研究。服务器怎么知道你以前调用过这个函数?不可能。
我对你的问题的回答是,你的实现是完全错误的,我强烈建议你找一个
getting started guide
对于表单登录如何在spring安全中工作,因为解释spring安全如何工作,不能用简单的答案来回答。我要做的就是把你和官方联系起来
Spring security FormLogin
文档,你应该开始阅读。