使用 angularJS 的 Spring Boot 安全性/登录身份验证

Posted

技术标签:

【中文标题】使用 angularJS 的 Spring Boot 安全性/登录身份验证【英文标题】:Spring Boot Security /login authentication with angularJS 【发布时间】:2019-03-13 12:40:43 【问题描述】:

所以我有了这个项目,我真正想做的就是让用户登录并访问特定页面:

安全

@Configuration
@EnableWebSecurity
public class MainSecurityConfig extends WebSecurityConfigurerAdapter 


    @Resource
    private UserDetailsServiceImpl userDetailsService;

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() 
        return new HttpSessionEventPublisher();
    


    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http
                .csrf().disable();

        http
                .authorizeRequests()
                .antMatchers("/", "/**", "/login/**", "/index.html", "/login.html", "/components/**", "/css/**", "/js/**", "/fonts/**", "/images/**", "/.sass-cache/**", "/services.html").permitAll()
                .anyRequest().authenticated();


        http.formLogin()
                .loginPage("/login")
                .failureForwardUrl("/login.html")
                .usernameParameter("user")
                .passwordParameter("password");



    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.authenticationProvider(authenticationProvider());
    


    @Bean
    public DaoAuthenticationProvider authenticationProvider() 
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    

当我从 angularjs 作为 POST 发送 /login 请求时,我点击了 UserDetailsServiceImpl,这很好,但用户名是空的。

UserDetailsS​​erviceImpl

@Service
public class UserDetailsServiceImpl implements UserDetailsService 
    @Resource
    private HttpSession httpSession;


    @Resource
    private UserDao userDao;


    @Override
    public UserDetails loadUserByUsername(String user) throws UsernameNotFoundException 

        User userByEmail = userDao.findUserByEmail(user);

        UserDetailsImpl userDetails = new UserDetailsImpl(userByEmail, httpSession.getId());

        return userDetails;
    

所以我做了一些谷歌搜索,它说 /login 请求必须是 GET,这本身就让我感到困惑,我们真的应该将用户名和密码插入 url 吗?还是我想错了。无论如何,这是 angularJS 代码:

$scope.loginUser = function () 
    $scope.user.user = $scope.email;
    $scope.user.password = $scope.password;
    $http.get("/login",  params: username: $scope.user.user, password: $scope.user.password);

我现在不再在 UserDetailsServiceImpl 内命中断点,而是得到了 404。

更新

更新处理url后,我现在发布它,但是服务器端传递的用户名是空的

$scope.loginUser = function () 
    $scope.user.username = $scope.email;
    $scope.user.password = $scope.password;
    $http.post("/api/authentication", $scope.user);

到这里一切都好,只是java处理它的时候

【问题讨论】:

【参考方案1】:

如果您使用的是 Angular,则您没有 loginPage,因为您正在编写 SPA 并且页面导航由 Angular 本身管理。

您应该使用仅定义登录提交 url 的loginProcessingUrl

    .and()
        .formLogin()
        .loginProcessingUrl("/api/authentication")
        .usernameParameter("username")
        .passwordParameter("password")

要提交您的登录信息,您需要输入 POST 而不是 GET。可能链接意味着访问登录页面的 url 不提交。

在上面的示例中,您必须使用 url /api/authentication 使用包含 usernamepassword 的正文执行 POST

另外,如果我看到您已经找到了解决方案,我已经发布了一个基于 Spring Boot 2.0 和 angular 6(angularjs 已经过时)的项目,带有 spring 安全性和状态身份验证(与您正在搜索的相同)

https://github.com/ValerioMC/vforge-stateful-auth

这只是一个起点。

【讨论】:

得到和以前一样的问题,发送的用户名是空的 已编辑答案。尝试按照链接中的教程进行操作。这是一个完整的示例,应该对您有所帮助。您还将找到 GitHub 源代码 我已经阅读了那篇确切的文章,他们进行了单独的身份验证来获取用户,但他们从未实际发布详细信息。一旦通过身份验证,他们就会重定向到“/login” 在GitHub上添加相关代码链接。用户通过身份验证后,由您来管理重定向 这是不正确的,formlogin()默认会在/login处使用spring生成的登录页面,如果没有另外指定。【参考方案2】:

问题出在我的 AngularJS $http.post 请求上,我通过为 'application/x-www-form-urlendcoded' 添加标头来解决它,因为它不是默认标头:

    $http(
        method: 'POST',
        url: '/api/authentication',
        headers: 'Content-Type': 'application/x-www-form-urlencoded',
        data: 'username=' + $scope.email + '&password=' + $scope.password
    );

【讨论】:

以上是关于使用 angularJS 的 Spring Boot 安全性/登录身份验证的主要内容,如果未能解决你的问题,请参考以下文章

spring boo的简单搭建(eclipse+springboot + redis + mysql + thymeleaf)

使用AngularJS配置Spring MVC

使用 Spring Security 和 AngularJS 预防 CSRF

使用 AngularJS 配置 Spring MVC

如何使用 Spring Security 和 Angularjs 保护 Spring Rest 服务?

使用 angularjs 使用安全的 spring rest 服务