首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在春季安全中从post方法中获取用户名?

如何在春季安全中从post方法中获取用户名?
EN

Stack Overflow用户
提问于 2019-03-03 12:03:22
回答 2查看 976关注 0票数 0

我在应用程序中使用spring-bootspring-security。我的目标是从post方法中获取当前注册用户的用户名。Get方法运行良好,但post方法不起作用。为什么?我该如何解决这个问题?

测试控制器

代码语言:javascript
复制
@GetMapping("/test")
public String test(Authentication authentication) {
    System.out.println(authentication.getName()); // <--------- It's working
    return "testfile";
}

@PostMapping("/test")
public String testPost(Authentication authentication) {
    System.out.println(authentication.getName()); // <--------- NOLL ERROR!
    return "testfile";
}

误差

代码语言:javascript
复制
java.lang.NullPointerException: null

用户

代码语言:javascript
复制
@Entity
@Table(name="user")
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private long id;
    @Column(name="mail")
    private String mail;
    @Column(name="password")
    private String password;
}

UserDAO

代码语言:javascript
复制
@Repository
public class UserDAO {
    @Autowired
    private EntityManager entityManager;
    public List<User> findAll() {
        return entityManager.unwrap(Session.class).createQuery("from User", User.class).getResultList();
    }
    public User findByMail(String mail){
        Session currentSession = entityManager.unwrap(Session.class);
        Query theQuery = currentSession.createQuery("from User where mail=:mail", User.class);
        theQuery.setParameter("mail", mail);
        List<User> users = theQuery.getResultList();
        if(users.isEmpty()){
            return new User();
        }
        return users.get(0);
    }
    public void saveOrUpdate(User user) {
        Session currentSession = entityManager.unwrap(Session.class);
        currentSession.saveOrUpdate(user);
    }
}

UserService

代码语言:javascript
复制
public interface UserService extends UserDetailsService{
    public List<User> findAll();
    public User findByMail(String mail);
    public void saveOrUpdate(User user);
}

UserServiceImpl

代码语言:javascript
复制
@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private UserDAO userDAO;
    @Autowired
    private UserRoleDAO userRoleDAO;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    @Override
    @Transactional
    public List<User> findAll() {
        return userDAO.findAll();
    }
    @Override
    @Transactional
    public User findByMail(String mail){
       return userDAO.findByMail(mail);
    }
    @Override
    @Transactional
    public void saveOrUpdate(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userDAO.saveOrUpdate(user);
    }
    @Override
    @Transactional
    public UserDetails loadUserByUsername(String mail) throws UsernameNotFoundException {
        User user = userDAO.findByMail(mail);
        List<UserRole> userRole = userRoleDAO.findByUserId(user.getId());
        if (user == null) {
            throw new UsernameNotFoundException("Invalid username or password.");
        }
        return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), mapRolesToAuthorities(userRole));
    }
    private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<UserRole> roles) {
        return roles.stream().map(role -> new SimpleGrantedAuthority(role.getRole())).collect(Collectors.toList());
    }
}

SecurityConfig

代码语言:javascript
复制
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private Environment env;

@Autowired
private DataSource dataSource;

@Autowired
private UserService userService;

RedirectAuthenticationSuccessHandler redirectAuthenticationSuccessHandler = new RedirectAuthenticationSuccessHandler();

RedirectAuthenticationFailureHandler redirectAuthenticationFailureHandler = new RedirectAuthenticationFailureHandler();

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication().dataSource(dataSource)
            .usersByUsernameQuery(env.getProperty("my.usersbyusernamequery"))
            .authoritiesByUsernameQuery(env.getProperty("my.authoritiesbyusernamequery"));
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http.authorizeRequests()
            .antMatchers("/anypage1/**").hasRole("MANAGER")
            .antMatchers("/anypage2/**").hasRole("ADMIN")
            .antMatchers("/test").hasRole("ADMIN")
            .authenticated()
            .antMatchers("/**").permitAll()
            .and()
            .formLogin().loginPage("/login").failureHandler(redirectAuthenticationFailureHandler)
            .loginProcessingUrl("/login-control").successHandler(redirectAuthenticationSuccessHandler).permitAll()
            .and()
            .logout().logoutUrl("/logout").permitAll().and().exceptionHandling().accessDeniedPage("/access-denied");
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.POST, "/anypage3").antMatchers(HttpMethod.POST, "/anypage4")
                  .antMatchers(HttpMethod.POST, "/test");
}

@Bean
public BCryptPasswordEncoder passwordEncoder()
{
    return new BCryptPasswordEncoder();
}

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
    auth.setUserDetailsService(userService);
    auth.setPasswordEncoder(passwordEncoder());
    return auth;
}

}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-04 10:18:45

代码语言:javascript
复制
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(HttpMethod.POST, "/anypage3").antMatchers(HttpMethod.POST, "/anypage4")
                  .antMatchers(HttpMethod.POST, "/test");
}

在post方法中忽略/test,因此它不会被spring安全筛选器过滤,请尝试删除它。

票数 0
EN

Stack Overflow用户

发布于 2019-03-03 12:23:35

您可以从SecurityContextHolder获得用户名

User = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();字符串名称= user.getUsername();//get当前登录用户名

在loadUserByUsername方法中,您可以在SecurityContextHolder上手动设置身份验证令牌,与在控制器中使用的相同

代码语言:javascript
复制
UsernamePasswordWithAttributesAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loadUserByUsername(username), password, authorities );
    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54968583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档