当前位置: 首页 > 知识库问答 >
问题:

Angular with Spring Security登录和身份验证

呼延弘方
2023-03-14

我们在前端使用AngularJS,在后端使用spring。Spring 安全应该进行身份验证和登录,但它甚至不能在 Spring 的教程 (https://spring.io/guides/tutorials/spring-security-and-angular-js/) 的帮助下工作。每次我们尝试登录“用户”服务时,主体对象都是空的。在前端,我们收到这个答案:data = Object {data: “”, status: 200, config: Object, statusText: “OK”} EVERYTIME。使用正确或不正确的数据登录并不重要...我读了很多文章,但我找不到解决方案。

我们的登录.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Login</title>
    <link rel="stylesheet" type="text/css" href="stylesheets/bootstrap.min.css" />
    <script src="scripts/angular.min.js"></script>
    <script src="scripts/login.js"></script>
    <style>
        body {
            position: relative;
        }
    </style>
</head>

<body ng-app="LoginApp">
    <div class="modal show" ng-controller="LoginController">
        <div class="modal-header">
            <h1 class="text-center">Login</h1>
        </div>
        <div class="modal-body">
            <form>
                <div class="control-group">
                    <div class="controls">
                        <input class="input-block-level" type="text" placeholder="Username" ng-model="username" ng-change="checkValid()" ng-disabled="requesting">
                    </div>
                </div>
                <div class="control-group">
                    <div class="controls">
                        <input class="input-block-level" type="password" placeholder="Password" ng-model="password" ng-change="checkValid()" ng-disabled="requesting">
                    </div>
                </div>
                <span class="error" ng-bind="errormessage" ng-show="error"></span>
                <!--
                <div class="control-group">
                    <label class="checkbox">
                        <input type="checkbox">Remember me</label>
                </div>
                -->
            </form>
        </div>
        <div class="modal-footer">
            <!--
            <button class="btn btn-link">Forgot password?</button>
            -->
            <button class="btn btnExtra btn-large btn-primary" ng-click="submitLogin()" ng-disabled="requesting || !valid">Login</button>
        </div>
    </div>
</body>

</html>

我们的login.js:

(function(angular) {
                const app = angular.module("LoginApp",[]);
                app.controller("LoginController", ["$scope", "$http", function($scope, $http){
                        $scope.username = "";
                        $scope.password = "";
                        $scope.errormessage = "";
                        $scope.error = false;
                        $scope.valid = false;
                        $scope.requesting = false;
                        $scope.submitLogin = function() {
                           $scope.requesting = true;
                           $scope.error = false;
                           const credentials = {
                               username: $scope.username,
                               password: $scope.password
                           };
                           const headers = credentials ? {authorization : "Basic "
                                + btoa(credentials.username + ":" + credentials.password)
                                 } : {};
                           $http.get("user", { headers: headers }).then(function(data){
                               if(data.data.name) {
                                   window.location.href = "/";
                               }
                               else {
                                   $scope.error = true;
                                   $scope.requesting = false;
                                   $scope.errormessage = "Username / Passwort ist falsch!";
                               }
                           },
                           function(reason) {
                               $scope.error = true;
                               $scope.requesting = false;
                               if(reason.status === 404 || reason.status === 408){
                                   $scope.errormessage = "Verbindung zum Server konnte nicht hergestellt werden!";
                               }else if (reason.status === 403){
                                   $scope.errormessage = "Username / Passwort ist falsch!";
                               }else{
                                   $scope.errormessage = "Unbekannter Fehler ist bei der Anfrage aufgetreten! Bitte versuchen Sie es erneut";
                               }
                           })
                        };
                        $scope.checkValid = function(){
                            if($scope.username != undefined && $scope.username != null && $scope.username.length > 1 &&
                            $scope.password != undefined && $scope.password != null && $scope.password.length > 1){
                                $scope.valid = true;
                            }else{
                                $scope.valid = false;
                            }
                        };
                    }
                ]);
            })(window.angular);

我们的认证服务(如教程或许多帖子中所述):

@RestController
public class UserController {
    @RequestMapping(value = "/user")
    public Principal user(Principal user) {
        return user;
    }
}

具有自定义过滤器的SecurityWebApp初始化程序,该过滤器应记录IP和用户名。

@Order(2)
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    @Override
    protected void afterSpringSecurityFilterChain(ServletContext servletContext) {
        super.beforeSpringSecurityFilterChain(servletContext);
        insertFilters(servletContext,new MultipartFilter(),new MDCFilter());
    }
}

最后我们的 Spring 安全配置

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;

@Configuration
@EnableWebSecurity(debug=true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
        .jdbcAuthentication()
             .dataSource(dataSource)
                .usersByUsernameQuery(
                        "select email,pwHash,true from user where email = ?")
                .authoritiesByUsernameQuery(
                        "select email, rolle_rollenname from user where email = ?");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/user", "/login", "/logout", "login.html").permitAll()
            .anyRequest().authenticated()
        .and()
            .csrf().csrfTokenRepository(csrfTokenRepository())
        .and()
            .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
        .formLogin()
            .loginPage("/login")
            //.logoutSuccessHandler(new customLogoutSuccessHandler())
            .and()
        .logout()
            .logoutUrl("/logout");
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
         web
            .ignoring()
            .antMatchers("/scripts/**")
            .antMatchers("/stylesheets/**");
    }

    private CsrfTokenRepository csrfTokenRepository() 
    { 
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository; 
    }
}

当使用自定义身份验证和默认登录页面时,它可以正常工作。也许login.html或login.js是错误的…

更新

当我在不指定登录信息的情况下使用.httpBasic()时,当我尝试访问安全的资源时,会出现一个浏览器对话框。我希望重定向到自定义登录页面,而不是浏览器对话框。如何做?

共有2个答案

籍利
2023-03-14

试试看:

.factory('AuthFactory', ['$http', 'contextPath', '$q', '$timeout', function ($http, contextPath, $q, $timeout) {

            function User() {
            };

            var currentUser = null;

            var userChangeCallbacks = [];

            var notifyUserChange = function (newUser) {
                angular.forEach(userChangeCallbacks, function (callback) {
                    $timeout(function () {
                        callback(newUser);
                    });
                });
            };

            var exported = {
                getCurrentUser: function () {
                    return currentUser;
                },
                refresh: function () {
                    return $q(function (resolve, reject) {
                        //Get the current user
                        $http.get(contextPath + '/rest/user/current')
                                .success(function (data) {
                                    currentUser = new User();
                                    for (var key in data) {
                                        currentUser[key] = data[key];
                                    }
                                    notifyUserChange(currentUser);
                                    resolve(currentUser);
                                })
                    });
                },
                registerUserChangeHandler: function (callback) {
                    console.log("registered handler: " + callback);
                    userChangeCallbacks.push(callback);
                }
            };

            return exported;
        }]);

然后在登录控制器中调用该刷新方法。

登录控制器

$scope.login = function (username, password) {
            UserService.login({
                'username': username,
                'password': password
            }, function () {
                AuthFactory.refresh();
                $state.go("home");
            });
        };
秦新立
2023-03-14

好的,我是通过使用JSON Web令牌(一种自定义无状态过滤器)获得的,每当他们提出要求时,都会将令牌返回给前端。

 类似资料:
  • 使用,https://github.com/firebase/FirebaseUI-Android/tree/master/codelabs/chat作为登录的参考,我在键入时似乎遇到了问题 我只能键入Auth的提供者,而不能键入,为什么会这样,它提示我键入社会提供者。

  • 问题内容: 我正在开发Flask应用程序,并使用Flask-security进行用户身份验证(反过来又在下面使用Flask-login)。 我有一条需要身份验证的路由。我正在尝试编写一个单元测试,该测试对经过身份验证的用户返回适当的响应。 在单元测试中,我正在创建一个用户并以该用户身份登录,如下所示: 在测试内返回正确的用户。但是,请求的视图始终返回的。 所述路线定义为: 我可以肯定我只是不完全了

  • 当使用Firebase身份验证匿名帐户时,它偶尔会在系统中创建一个新的用户ID,有时它会使用相同的用户ID。我真的希望每次都能创建相同的用户ID,这样匿名用户仍然可以在应用程序中维护相同的进度/数据。这实际上是我开始使用Firebase的原因。即使在重新启动应用程序等之后,我如何始终维护一个匿名帐户来保持相同的用户ID? 我希望用户每次以访客身份玩游戏时都能获得相同的ID。我看到有些应用程序在卸载

  • 在控制台中写入函数:anonymousUser true[ROLE_ANONYMOUS] 并且应该是user1 true[ROLE_USER]user1

  • 本文向大家介绍firebase-authentication Google Plus登录身份验证,包括了firebase-authentication Google Plus登录身份验证的使用技巧和注意事项,需要的朋友参考一下 示例 使用Plus登录验证用户 onCreate onStart() 获取资料信息 使用Firebase进行身份验证, onActivityResult 登出      

  • 我用Spring Security做了一个概念验证,以便使用PRE_AUTH_FILTER过滤器执行预认证。它工作正常,但我想知道如果这个过滤器不起作用,我是否可以重定向到登录页面,因为我得到HTTP 403。< br >我的意思是,如果初始请求的头中不包含SM_USER字段,我如何重定向到登录页面?我需要考虑这两种情况(当它包含字段- SM_USER -和不包含时),但我无法让它工作。有什么想法