我正在做一个基于spring boot + Angularjs构建的应用程序 我根据此博文发表的身份验证:https://spring.io/guides/tutorials/spring-security-and-angular-js/ 所以我获得了基本的用户名/密码或启用了OAuth2
我想在其中添加Remmeber me功能。我有AuthService
AuthService.authenticate = function (credentials, callback) {
var headers = credentials ? {
authorization: "Basic "
+ btoa(credentials.username + ":" + credentials.password)
} : {};
$http.get('api/user/', {headers: headers}, {timeout: 5000}).then(
function (response) {
var data = response.data;
if (data.id) {
$rootScope.authenticated = true;
$rootScope.principal = data;
$translate.use($rootScope.principal.language);
$location.search('lang', $rootScope.principal.language);
AvatarService.getUserAvatar($rootScope.principal);
$log.debug("[DEBUG] User logged in " + $rootScope.principal.id);
} else {
$rootScope.authenticated = false;
}
callback && callback();
},
function () {
$rootScope.authenticated = false;
callback && callback();
});
};
在登录控制器中,我得到了处理:
$scope.credentials = {};
//LOGIN
$scope.login = function () {
AuthService.authenticate($scope.credentials, function () {
if ($rootScope.authenticated) {
$location.path("/");
AlertService.clearAlerts();
} else {
$location.path("/login");
AlertService.addError('user.login.failed');
}
});
};
在Spring安全性上,我设置它通常是我设置它,(配置的一部分)
....
.and().formLogin()
.loginPage("/#/login")
.and().rememberMe()
.rememberMeServices(rememberMeServices())
.key("remember-me-key")
.and().addFilterBefore(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf()
....
但是我的猜测是期待使用remember-me和而不是基本的auth
如何调整以便能够记住我? 我可以通过post执行调用以使用j_username j_password登录并记住我吗?
答案 0 :(得分:1)
您可以配置spring boot服务器以将auth令牌发回客户端。在客户端(Angular)中,将令牌保存在某处(本地存储/ cookie)。然后,您可以在应用首次加载时检查令牌是否存在。 在处理Web客户端身份验证时,JWT令牌非常好。
例如,如果我的安全配置文件中有这段代码。
.authorizeRequests()
.antMatchers("/", "/index.html", "/login.html", "/home.html").permitAll()
.anyRequest()
.authenticated().and()
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
我可以轻松实现authenticationSuccessHandler
并在成功登录后向用户发出身份验证令牌或身份验证Cookie,或两者都发回。
public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
... bla bla bla
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication ) throws IOException, ServletException {
clearAuthenticationAttributes(request);
User user = (User)authentication.getPrincipal();
String jws = tokenHelper.generateToken( user.getUsername() );
// cookie in response
Cookie authCookie = new Cookie( TOKEN_COOKIE, ( jws ) );
authCookie.setPath( "/" );
authCookie.setHttpOnly( true );
authCookie.setMaxAge( EXPIRES_IN );
response.addCookie( authCookie );
// token in response
UserTokenState userTokenState = new UserTokenState(jws, EXPIRES_IN);
String jwtResponse = objectMapper.writeValueAsString( userTokenState );
response.setContentType("application/json");
response.getWriter().write( jwtResponse );
}
}
更多细节可在springboot-jwt-starter中找到。这是一个使用spring boot和AngularJS的入门套件项目。
如果您想使用Angular实现Spring启动安全性,The Login Page: Angular JS and Spring Security Part II系列是一个非常好的阅读材料。
答案 1 :(得分:0)
我还在开发Spring + Angular2应用程序。在我的例子中,后端返回2个令牌(访问令牌和刷新令牌)。之后我添加了授权'每个请求的标题:' Bearer' + this.accessToken。
答案 2 :(得分:0)
您可以使用带有Angular和基本身份验证的Spring remember-me服务,您必须使用post发送remember-me参数。
以下是Angular2的示例:
import {Injectable} from "@angular/core";
import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
import {CSRF_URL, LOGIN_URL, LOGOUT_URL} from "./auth.constant";
export interface RespAccess {
email?: String;
name: string;
permissions: [string];
}
@Injectable()
export class AuthenticationService {
constructor(private http: HttpClient) {}
login(username: string, password: string, rememberme: boolean): Observable<RespAccess> {
let headers = new HttpHeaders();
headers = headers.append('Authorization', 'Basic ' + btoa(username + ':' + password));
headers = headers.append('X-Requested-With', 'XMLHttpRequest'); // to suppress 401 browser popup
const params = new HttpParams().append('remember-me', (rememberme ? 'true' : 'false' ));
return this.http.post<RespAccess>(LOGIN_URL,'', {headers, params});
}
logout() : Observable<any> {
return this.http.post<any>(LOGOUT_URL, '');
}
getCSRFToken() {
this.http.get<any>(CSRF_URL) // /api/auth/csrf
.subscribe();
}
}
如果您使用CSRF保护,则必须在登录前获取CSRF令牌。你可以这样做只是访问一个返回令牌的不安全的URL,这是Spring服务器端控制器中的方法:
@RequestMapping("/api/auth/csrf")
public CsrfToken csrf(CsrfToken token) {
return token;
}