- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我必须说我对整个模型非常困惑,我需要帮助将所有 float 部分粘合在一起。
我没有做 Spring REST,只是简单的 WebMVC Controller 。
我的使命:我想要一个带有用户名+通过身份验证的表单登录。我想针对 3rd 方服务进行身份验证。成功后我想返回一个 cookie 但不使用默认的 cookie token 机制。我希望 cookie 有一个 JWT token 。通过利用 cookie 机制,每个请求都将使用 JWT 发送。
因此,为了分解它,我需要处理以下模块:
验证成功后用我的自定义实现替换 cookie session token
在每次请求时从 cookie 中解析 JWT(使用过滤器)
从 JWT 中提取用户详细信息/数据以供 Controller 访问
什么令人困惑? (请指正我错的地方)
第三方认证
要针对第 3 方进行身份验证,我需要通过扩展 AuthenticationProvider 来拥有一个自定义提供程序
public class JWTTokenAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate( Authentication authentication ) throws AuthenticationException {
// auth against 3rd party
// return Authentication
return new UsernamePasswordAuthenticationToken( name, password, new ArrayList<>() );
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals( UsernamePasswordAuthenticationToken.class );
}
}
问题:
用 JWT 替换 cookie token
不知道如何优雅地做到这一点,我可以想到很多方法,但它们不是 Spring Security 的方法,我不想打破常规。非常感谢您在这里提出任何建议!
使用来自 cookie 的每个请求解析 JWT
据我了解,我需要像这样扩展 AbstractAuthenticationProcessingFilter
public class CookieAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
@Override
public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response )
throws AuthenticationException, IOException, ServletException {
String token = "";
// get token from a Cookie
// create an instance to Authentication
TokenAuthentication authentication = new TokenAuthentication(null, null);
return getAuthenticationManager().authenticate(tokenAuthentication);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
super.doFilter(req, res, chain);
}
}
问题:
似乎我已经拥有了我需要的所有部分,除了 cookie session 替换,但我无法将它们放入一个连贯的模型中,我需要一个对机制足够了解的人,这样我就可以将所有这些整合到单个模块。
更新 1
此过滤器将自己注册到 POST -> "/login",然后创建一个 UsernamePasswordAuthenticationToken 实例并将控制权传递给下一个过滤器。
问题是设置 cookie session 的位置......
更新 2
dos 的这一部分给出了我所缺少的顶级流程,对于正在经历这个的人来说,看看这里... http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#tech-intro-authentication
本节关于 AuthenticationProvider... http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#core-services-authentication-manager
更新 3 - 工作案例,这是最好的方法吗?
因此,在深入研究了 Spring Security 文档及其源代码后,我得到了初始模型。现在,这样做,我意识到有不止一种方法可以做到这一点。关于为什么选择这种方式 VS Denys 下面提出的任何建议?
下面的工作示例...
最佳答案
要让它按照原始帖子中描述的方式工作,这就是需要发生的事情......
自定义过滤器
public class CookieAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public CookieAuthenticationFilter( RequestMatcher requestMatcher ) {
super( requestMatcher );
setAuthenticationManager( super.getAuthenticationManager() );
}
@Override
public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response )
throws AuthenticationException, IOException, ServletException {
String token = "";
// get token from a Cookie
Cookie[] cookies = request.getCookies();
if( cookies == null || cookies.length < 1 ) {
throw new AuthenticationServiceException( "Invalid Token" );
}
Cookie sessionCookie = null;
for( Cookie cookie : cookies ) {
if( ( "someSessionId" ).equals( cookie.getName() ) ) {
sessionCookie = cookie;
break;
}
}
// TODO: move the cookie validation into a private method
if( sessionCookie == null || StringUtils.isEmpty( sessionCookie.getValue() ) ) {
throw new AuthenticationServiceException( "Invalid Token" );
}
JWTAuthenticationToken jwtAuthentication = new JWTAuthenticationToken( sessionCookie.getValue(), null, null );
return jwtAuthentication;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
super.doFilter(req, res, chain);
}
}
身份验证提供者
将提供者附加到由 UsernamePasswordAuthenticationFilter 生成的 UsernamePasswordAuthenticationToken,后者将自身附加到“/login” POST。对于带有 POST 到 "/login"的 formlogin 将生成 UsernamePasswordAuthenticationToken 并且您的提供者将被触发
@Component
public class ApiAuthenticationProvider implements AuthenticationProvider {
@Autowired
TokenAuthenticationService tokenAuthService;
@Override
public Authentication authenticate( Authentication authentication ) throws AuthenticationException {
String login = authentication.getName();
String password = authentication.getCredentials().toString();
// perform API call to auth against a 3rd party
// get User data
User user = new User();
// create a JWT token
String jwtToken = "some-token-123"
return new JWTAuthenticationToken( jwtToken, user, new ArrayList<>() );
}
@Override
public boolean supports( Class<?> authentication ) {
return authentication.equals( UsernamePasswordAuthenticationToken.class );
}
}
自定义身份验证对象
对于 JWT,我们希望拥有自己的身份验证 token 对象,以便在堆栈中携带我们想要的数据。
public class JWTAuthenticationToken extends AbstractAuthenticationToken {
User principal;
String token;
public JWTAuthenticationToken( String token, User principal, Collection<? extends GrantedAuthority> authorities ) {
super( authorities );
this.token = token;
this.principal = principal;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return principal;
}
public void setToken( String token ) {
this.token = token;
}
public String getToken() {
return token;
}
}
身份验证成功处理程序
当我们的自定义提供程序通过针对第 3 方对用户进行身份验证并生成 JWT token 来完成它的工作时,就会调用它,这是 Cookie 进入响应的地方。
@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if( !(authentication instanceof JWTAuthenticationToken) ) {
return;
}
JWTAuthenticationToken jwtAuthenticaton = (JWTAuthenticationToken) authentication;
// Add a session cookie
Cookie sessionCookie = new Cookie( "someSessionId", jwtAuthenticaton.getToken() );
response.addCookie( sessionCookie );
//clearAuthenticationAttributes(request);
// call the original impl
super.onAuthenticationSuccess( request, response, authentication );
}
}
将这一切联系在一起
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Required
ApiAuthenticationProvider apiAuthProvider;
@Autowired @Required
AuthenticationSuccessHandler authSuccessHandler;
@Autowired @Required
SimpleUrlAuthenticationFailureHandler authFailureHandler;
@Override
protected void configure( AuthenticationManagerBuilder auth ) throws Exception {
auth.authenticationProvider( apiAuthProvider );
}
@Override
protected void configure( HttpSecurity httpSecurity ) throws Exception {
httpSecurity
// don't create session
.sessionManagement()
.sessionCreationPolicy( SessionCreationPolicy.STATELESS )
.and()
.authorizeRequests()
.antMatchers( "/", "/login", "/register" ).permitAll()
.antMatchers( "/js/**", "/css/**", "/img/**" ).permitAll()
.anyRequest().authenticated()
.and()
// login
.formLogin()
.failureHandler( authFailureHandler )
//.failureUrl( "/login" )
.loginPage("/login")
.successHandler( authSuccessHandler )
.and()
// JWT cookie filter
.addFilterAfter( getCookieAuthenticationFilter(
new AndRequestMatcher( new AntPathRequestMatcher( "/account" ) )
) , UsernamePasswordAuthenticationFilter.class );
}
@Bean
SimpleUrlAuthenticationFailureHandler getAuthFailureHandler() {
SimpleUrlAuthenticationFailureHandler handler = new SimpleUrlAuthenticationFailureHandler( "/login" );
handler.setDefaultFailureUrl( "/login" );
//handler.setUseForward( true );
return handler;
}
CookieAuthenticationFilter getCookieAuthenticationFilter( RequestMatcher requestMatcher ) {
CookieAuthenticationFilter filter = new CookieAuthenticationFilter( requestMatcher );
filter.setAuthenticationFailureHandler( authFailureHandler );
return filter;
}
}
关于java - Spring Security Cookie + JWT 认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341114/
在我的主要组件中,我有: mounted() { window.$cookie.set('cookie_name', userName, expiringTime); }, 这会产生以下错误:
我正在学习 cookie,并且我想知道在编写依赖 cookie 来存储状态的 Web 应用程序时浏览器的支持情况。 对于每个域/网站,可以向浏览器发送多少个 Cookie,大小是多少? 如果发送并存储
我已经为我的站点设置了一个 cdn,并将其用于 css、js 和图像。 网站只提供那些文件 我的问题是 firefox 中的页面速度插件对于我的图片请求,我看到了一个 cookie Cookie fc
在阅读了 Internet 上的文档和帖子后,我仍然无法解决 jMeter 中的 Cookie Manager 问题。 我在响应头中得到了 sid ID,但它没有存储在我的 cookie 管理器中。
我正在 Node.JS 中处理一些类似浏览器的 cookie 处理,想知道从 NodeJS and HTTP Client - Are cookies supported? 开始对这段代码进行扩展到什
我正在此堆栈上构建自托管 Web 服务器:欧文南希网络 API 2 我正在使用 Katana 的 Microsoft.Owin.Security.Cookies 进行类似表单的身份验证。我得到了 Se
我有一个从另一个网站加载资源的网站。我已经能够确定: 第三方网站在用户的浏览器上放置 cookie。 如果我在浏览器设置中禁用第三方 cookie,第三方网站将无法再在浏览器上放置 cookie。 该
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我正在使用 python mechanize 制作登录脚本。我已经读到 Mechanize 的 Browser() 对象将自动处理 cookie 以供进一步请求。 我怎样才能使这个 cookie 持久
我正在尝试在 www.example.com 和 admin.other.example.com 之间共享 cookie 我已经能够使其与 other.example.com 一起使用,但是无法访问子
我设置了一个域为 .example.com 的 cookie .它适用于我网站上的每个一级子域,应该如此。 但是,它不适用于 n 级子域,即 sub.subdomain.example.com和 to
我想让用户尽可能长时间地登录。 我应该使用什么? 普通 cookies 持久性 cookie 快闪 cookies ip地址 session 或这些的某种组合? 最佳答案 我认为 Flash cook
如果给定的 Web 服务器只能读取其域内设置的 cookie,那么 Internet 广告商如何从其网络外的网站跟踪用户的 Web 流量? 是否存在某种“supercookie”全局广告系统,允许广告
我知道一个 cookie 可以容纳多少数据是有限制的,但是我们可以设置多少个 cookie 有限制吗? 最佳答案 来自 http://www.ietf.org/rfc/rfc2109.txt Prac
如果我拒绝创建 cookie,则在我的浏览器中创建名称为 __utma、__utmb 等的 cookie。我认为这个 cookie 是用于谷歌分析的。任何人都知道谷歌如何创建这个 cookie,即使浏
我有一个生产环境和一个登台环境。我想知道我是否可以在环境之间沙箱 cookie。我的设置看起来像 生产 domain.com - 前端 SPA api.domain.com - 后端节点 分期 sta
我想知道浏览器(即 Firefox )和网站的交互。 当我将用户名和密码提交到登录表单时,会发生什么? 我认为该网站向我发送了一些 cookie,并通过检查这些 cookie 来授权我。 cookie
我在两个不同的域中有两个网络应用程序 WebApp1 和 WebApp2。 我在 HttpResponse 的 WebApp1 中设置 cookie。 如何从 WebApp2 中的 HttpReque
我正在使用Dartium“Version 34.0.1847.0 aura(264987)”,并从Dart创建一个websocket。但是,如果不是httpOnly,我的安全 session cook
我从 Headfirst Javascript 书中获取了用于 cookie 的代码。但由于某种原因,它不适用于我的浏览器。我主要使用chrome和ff,并且我在chrome中启用了本地cookie。
我是一名优秀的程序员,十分优秀!