简体   繁体   English

使用angularJS的Spring Boot Security /登录身份验证

[英]Spring Boot Security /login authentication with angularJS

So I have this project, which really all I want to do is be able to have a user log in and get access to a specific page: 因此,我有了这个项目,实际上我要做的就是能够让用户登录并访问特定页面:

Security 安全

@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;
    }

When I sent the /login request from angularjs as a POST I was hitting the UserDetailsServiceImpl which is good, but the username was coming in empty. 当我从angularjs发送POST的/ login请求时,我碰到了很好的UserDetailsServiceImpl ,但是用户名为空。

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;
    }
}

So I did some googling and it said that the /login request has to be GET , which in itself confused me, should we really be plonking the username and password into the url? 所以我做了一些谷歌搜索,它说/ login请求必须是GET ,这本身使我感到困惑,我们是否真的应该将用户名和密码输入url中? Or am I thinking about this wrong. 还是我在想这个错误。 Anyway, here's the angularJS code: 无论如何,这是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}});

I no longer hit the breakpoints now within UserDetailsServiceImpl and rather I am getting a 404. 我现在不再在UserDetailsServiceImpl达到断点,而是得到了404。

UPDATE UPDATE

After updating the processing url, I now post it but the username that get's passed server-side is empty 更新处理网址后,我现在将其发布,但是通过服务器端传递的用户名为空

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

Everything up to here is fine, it's just when java handles it 到这里为止的一切都很好,只是在Java处理它的时候

If you are using Angular you have not a loginPage because you are writing a SPA and page navigation is managed by Angular itself. 如果您使用的是Angular,则由于您正在编写SPA且没有由Angular本身管理页面导航的loginPage页面。

You should use loginProcessingUrl that defines only the login submission url 您应该使用loginProcessingUrl ,它仅定义登录提交网址

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

To submit you login you need to do a POST not a GET . 要提交您的登录名,您需要执行POST而不是GET Probably links mean url to access a login page not to submit. 链接可能意味着访问登录页面而不提交的URL。

In the example above you have to do a POST using url /api/authentication with a body containing username and password 在上面的示例中,您必须使用url /api/authentication和包含usernamepassword的正文进行POST

Also if i've seen you already found the solution, i've published a project based on Spring Boot 2.0 and angular 6 (angularjs is quite outdated) with spring security and a stateful authentication (the same you were searching for) 另外,如果我已经看到您已经找到了解决方案,那么我已经发布了一个基于Spring Boot 2.0和angular 6(Angularjs已经过时)的项目,该项目具有spring安全性和有状态身份验证(与您搜索的相同)

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

It's just a starting point. 这只是一个起点。

The issue was with my AngularJS $http.post request, I solved it by adding headers for 'application/x-www-form-urlendcoded' as it is not the default header: 问题出在我的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
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM