0

我对 Spring Security 有疑问。

我正在尝试使用 mysql 数据检查进行身份验证。我正在使用 AngularJs、Spring Boot 和 Spring Security。

我有一个由 $http.post(...) 调用的 webservice rest。当我启动我的应用程序时,如果我使用 chrome 插件“Advanced Rest Client”>“ http://localhost:8080/check-login ”测试我的 web 服务;它有效,我收到代码 200:OK。

但是,如果我想通过 Chrome 使用相同的 URL 访问我的网络服务。带有身份验证功能的窗口。我认为这是 Spring Security 的预认证。但我不知道如何禁用它。

这是一个问题,因为当我想用浏览器访问 Web 服务时,它说:“ http://localhost:8080/check-login 401 unauthaurized”

编辑:这是我的代码:

HTML:

<form role="form" ng-submit="controller.login()">

    <div class="form-group">
        <label for="username">Username:</label> 
        <input type="text" class="form-control" id="username" name="username" ng-model="controller.credentials.username"/>
    </div>

    <div class="form-group">
        <label for="password">Password:</label> 
        <input type="password" class="form-control" id="password" name="password" ng-model="controller.credentials.password"/>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>

</form>

JS:

myModule.controller('NavCtrl',function($rootScope, $location, $http){

    var self = this

    var authenticate = function(credentials, callback) {


        var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};

        $http.get('user', {headers : headers}).then(
            function(response) {
                if (response.data.name) {
                    $rootScope.authenticated = true;
                } else {
                    $rootScope.authenticated = false;
                }
                callback && callback();
            }, 
            function() {
                $rootScope.authenticated = false;
                callback && callback();
            }
        );

    }

    authenticate();
    self.credentials = {};

    self.login = function() {
        authenticate(self.credentials, function() {
            if ($rootScope.authenticated) {
                $location.path("/");
                self.error = false;
            } else {
                $location.path("/login");
                self.error = true;
            }
        });
    };

});

我的 Java 休息:

@RestController
public class TestRest {

    @RequestMapping("/user")
    public Principal user(Principal user){
        return user;
    }

}

我的 Java Spring Boot 和安全配置:

@SpringBootApplication
public class BusinessBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(BusinessBootApplication.class, args);
    }

    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
            .httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/index.html","/home.html","/login.html","/").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
            .csrf()
            .csrfTokenRepository(csrfTokenRepository());
        }

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

最后,我的关于 UserDetailsS​​ervice 的 Java

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    public UserDao userDao;

    @Autowired
    public UserDetailsServiceImpl(UserDao _userDao) {
        super();
        userDao = _userDao;
    }

    @Override
    public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {

        UserDetailsImpl userDetailsImpl = null;

        User user = userDao.findByLogin(arg0);

        if(user == null){
            throw new UsernameNotFoundException("Login not found");
        } else{
            userDetailsImpl = new UserDetailsImpl(user);
        }

        return userDetailsImpl;
    }

}




public class UserDetailsImpl implements UserDetails {

    /** The Constant serialVersionUID. */
    private static final long serialVersionUID = 1L;

    /** The _username. */
    private String username;

    /** The _password. */
    private String password;

    public UserDetailsImpl(User user) {
        username = user.getLogin();
        password = user.getPwd();
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return false;
    }

}

你有想法吗 ?谢谢

4

3 回答 3

1

此窗口是 Basic Authentication 窗口,在您的代码中您使用的是 Basic Authentication ( httpBasic ):

http.httpBasic()
     .and()
     .authorizeRequests()
     .antMatchers("/index.html","/home.html","/login.html","/").permitAll()
     .anyRequest()
     .authenticated()

因此,如果您尝试访问受保护的 url,请配置您的 spring 安全性以应用基本身份验证。

基于此配置,Chrome 正在检查 http 请求是否包含 Authentication Header(包括用户凭据),如果是则不打开身份验证窗口,否则 Chrome 将打开身份验证窗口以插入用户名和密码。

要解决窗口问题,您需要按照您在下面的代码中编写的 angularJS 代码处理基本身份验证(请通过监视 chrome 开发人员工具中的请求标头检查此代码是否正常工作)

var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};

        $http.get('user', {headers : headers}).then(
            function(response) {
                if (response.data.name) {
                    $rootScope.authenticated = true;
                } else {
                    $rootScope.authenticated = false;
                }
                callback && callback();
            }, 
            function() {
                $rootScope.authenticated = false;
                callback && callback();
            }
        );

请注意:当您使用 Advanced Rest Client Tool 时,您可以通过 Basic 身份验证标头,如果您不通过此标头,则不会打开身份验证窗口。

于 2016-05-17T20:17:22.640 回答
0

/check-login 是您的登录页面吗?如果是-

这个 url 也应该放在 antmatcher("/check-login").permitAll() 中。

/check-login

“check-login” url 用于登录。如果你不把 permitAll 放在里面,/check-login 页面也需要认证。这将禁用 Spring Security 的身份验证。

于 2016-05-17T09:53:31.823 回答
0

Chrome 从与 Internet Explorer 相同的 Internet 选项中获取其受信任的站点设置。您可以在此处从 Chrome 访问对话框:

属性 -> 显示高级设置 -> 更改代理设置 -> 安全 -> 受信任的站点

请注意:首次访问受信任的站点时,系统会要求您登录。

于 2016-05-17T09:49:04.410 回答