栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何为单页AngularJS应用程序实现基本的Spring安全性(会话管理)

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何为单页AngularJS应用程序实现基本的Spring安全性(会话管理)

其余API有2个选项:有状态或无状态。

第一个选项:HTTP会话身份验证-“经典” Spring
Security身份验证机制。如果计划在多台服务器上扩展应用程序,则需要具有带有粘性会话的负载平衡器,以便每个用户都位于同一台服务器上(或将Spring
Session与Redis一起使用)。

第二个选择:您可以选择OAuth或基于令牌的身份验证。

OAuth2是一种无状态的安全性机制,因此,如果要跨多台机器扩展应用程序,则可能更希望使用它。Spring
Security提供了OAuth2实现。OAuth2的最大问题是需要具有多个数据库表才能存储其安全令牌。

与OAuth2一样,基于令牌的身份验证是一种无状态的安全机制,因此,如果要在多个不同的服务器上进行扩展,它是另一个不错的选择。Spring
Security默认情况下不存在此身份验证机制。与OAuth2相比,它更易于使用和实现,因为它不需要持久性机制,因此它适用于所有SQL和NoSQL选项。此解决方案使用自定义令牌,该令牌是您的用户名,令牌的到期日期,密码和密钥的MD5哈希。这样可以确保如果有人窃取了您的令牌,那么他将无法提取您的用户名和密码。

我建议您研究JHipster。它将使用REST
API(使用Spring
Boot)和前端(使用AngularJS)为您生成一个Web应用程序框架。生成应用程序框架时,它将要求您在我上面描述的3种身份验证机制之间进行选择。您可以重用JHipster在Spring
MVC应用程序中生成的代码。

这是JHipster生成的TokenProvider的示例:

public class TokenProvider {    private final String secretKey;    private final int tokenValidity;    public TokenProvider(String secretKey, int tokenValidity) {        this.secretKey = secretKey;        this.tokenValidity = tokenValidity;    }    public Token createToken(UserDetails userDetails) {        long expires = System.currentTimeMillis() + 1000L * tokenValidity;        String token = userDetails.getUsername() + ":" + expires + ":" + computeSignature(userDetails, expires);        return new Token(token, expires);    }    public String computeSignature(UserDetails userDetails, long expires) {        StringBuilder signatureBuilder = new StringBuilder();        signatureBuilder.append(userDetails.getUsername()).append(":");        signatureBuilder.append(expires).append(":");        signatureBuilder.append(userDetails.getPassword()).append(":");        signatureBuilder.append(secretKey);        MessageDigest digest;        try { digest = MessageDigest.getInstance("MD5");        } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("No MD5 algorithm available!");        }        return new String(Hex.enpre(digest.digest(signatureBuilder.toString().getBytes())));    }    public String getUserNameFromToken(String authToken) {        if (null == authToken) { return null;        }        String[] parts = authToken.split(":");        return parts[0];    }    public boolean validateToken(String authToken, UserDetails userDetails) {        String[] parts = authToken.split(":");        long expires = Long.parseLong(parts[1]);        String signature = parts[2];        String signatureToMatch = computeSignature(userDetails, expires);        return expires >= System.currentTimeMillis() && signature.equals(signatureToMatch);    }}

安全配置:

@Configuration@EnableWebSecuritypublic class SecurityConfiguration extends WebSecurityConfigurerAdapter {    @Inject    private Http401UnauthorizedEntryPoint authenticationEntryPoint;    @Inject    private UserDetailsService userDetailsService;    @Inject    private TokenProvider tokenProvider;    @Bean    public PasswordEnprer passwordEnprer() {        return new BCryptPasswordEnprer();    }    @Inject    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {        auth .userDetailsService(userDetailsService)     .passwordEnprer(passwordEnprer());    }    @Override    public void configure(WebSecurity web) throws Exception {        web.ignoring() .antMatchers("/scripts*.{js,html}");    }    @Override    protected void configure(HttpSecurity http) throws Exception {        http .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint)        .and() .csrf() .disable() .headers() .frameOptions() .disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS)        .and() .authorizeRequests()     .antMatchers("/api/register").permitAll()     .antMatchers("/api/activate").permitAll()     .antMatchers("/api/authenticate").permitAll()     .antMatchers("/protected    @Bean    evaluationContextExtension securityExtension() {        return new evaluationContextExtensionSupport() { @Override public String getExtensionId() {     return "security"; } @Override public SecurityexpressionRoot getRootObject() {     return new SecurityexpressionRoot(SecurityContextHolder.getContext().getAuthentication()) {}; }        };    }}

以及相应的AngularJS配置:

'use strict';angular.module('jhipsterApp')    .factory('AuthServerProvider', function loginService($http, localStorageService, base64) {        return { login: function(credentials) {     var data = "username=" + credentials.username + "&password="         + credentials.password;     return $http.post('api/authenticate', data, {         headers: {  "Content-Type": "application/x-www-form-urlenpred",  "Accept": "application/json"         }     }).success(function (response) {         localStorageService.set('token', response);         return response;     }); }, logout: function() {     //Stateless API : No server logout     localStorageService.clearAll(); }, getToken: function () {     return localStorageService.get('token'); }, hasValidToken: function () {     var token = this.getToken();     return token && token.expires && token.expires > new Date().getTime(); }        };    });

authInterceptor:

.factory('authInterceptor', function ($rootScope, $q, $location, localStorageService) {    return {        // Add authorization token to headers        request: function (config) { config.headers = config.headers || {}; var token = localStorageService.get('token'); if (token && token.expires && token.expires > new Date().getTime()) {   config.headers['x-auth-token'] = token.token; } return config;        }    };})

将authInterceptor添加到$ httpProvider中:

.config(function ($httpProvider) {    $httpProvider.interceptors.push('authInterceptor');})

希望这会有所帮助!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/371763.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号