春季启动安全性通过令牌识别

时间:2018-10-31 23:20:09

标签: firebase spring-boot spring-security firebase-security

我有一个应用程序,我想与我的rest-api建立连接。

每个用户都将获得一个“令牌”,该令牌将由google和co自动刷新。在我的请求中,我将发送令牌,如果可以将令牌解析为用户,则应答复该请求;否则,如果令牌不是最新的,我只想放弃该请求并返回错误。

还有一些可能性吗?

感谢您的帮助!

当前开始:

https://gist.github.com/PascalKu/97bca9506ad4f31c9e13f8fe8973d75b

1 个答案:

答案 0 :(得分:0)

您需要在spring中实现自定义身份验证。我做了同样的事情,但是我有一个数据库,如:

fb_email_address | user_id | other_fields ...

您必须创建以下类:

@Component
class TokenAuthenticationFilter extends OncePerRequestFilter {
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain) {
        String theToken = request.getParameter('theToken');
        TokenAuthentication tokenAuth = new TokenAuthentication(theToken)
        SecurityContextHolder.getContext().setAuthentication(tokenAuth)   
    }
}

您需要将身份验证提供程序添加到spring的安全系统中:

@Configuration
@EnableWebSecurity
class WebConfigHolder extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {
    @Autowired private TokenAuthenticationProvider tokenAuthenticationProvider

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(tokenAuthenticationProvider)
    }
}

实施身份验证提供程序,实际上会检查令牌是否有效。

@Component
class TokenAuthenticationProvider implements AuthenticationProvider {

//called by provider manager at some point during execution of security filters, I think
//it's the security api's job to call this
//the fbauthentication we create in our fbauthenticationfilter gets passed into this
@Override
@Transactional
Authentication authenticate(Authentication auth) {
    TokenAuthentication tokenAuthentication = (TokenAuthentication) auth;
    String theToken = auth.getThetoken();

    boolean theTokenIsInDB = ///CHECK TO SEE IF TOKEN IS IN DB
    if(theTokenIsInDB) {
        TokenAuthentication t = new TokenAuthentication();
        t.setAuthenticated(true);
        return t;
    } else {
        throw new BadCredentialsException("Could not find user");
    }
}

@Override
boolean supports(Class<?> authentication) {
    boolean ret = TokenAuthentication.isAssignableFrom(authentication)
    return TokenAuthentication.isAssignableFrom(authentication)
}
}

您需要一个简单的身份验证类,该类只是用于在spring等待线程到达spring安全过滤器时存储凭据的对象;一旦到达该过滤器,它将身份验证对象传递给支持它们的提供程序。这使您可以使用多种身份验证方法,例如FB,Google,自定义令牌等。在我的应用中,我使用FB令牌,在我的提供商中,我检查FB令牌是否对应于我的白名单中的授权电子邮件地址电子邮件地址。如果是这样,则用户可以访问我的应用。

public class TokenAuthentication extends Authentication{
    String token;
    boolean isAuthenticated = false;
    public TokenAuthentication(String theToken) { this.token = theToken;}
    //getters and setters
}

此代码的全部作用是,每当有人访问您的API时(例如/ api / person / get?theToken = 132x8591dkkad8FjajamM9

),
  1. 您创建的过滤器将在每个请求上运行。它检查是否传入了Token,并将TokenAuthentication添加到spring安全中。
  2. 在过滤器链中的某个点上,spring安全过滤器将运行,它将看到已创建TokenAuthentication,并将搜索可以对此执行身份验证的提供程序。恰好是您的TokenAuthenticationProvider。
  3. TokenAuthenticationProvider进行实际身份验证。如果返回的isAuthenticated设置为true的身份验证对象,则将允许用户访问该api调用。
  4. 通过身份验证后,用户无需再次传递令牌,直到清除其cookie或使会话无效为止。因此,他可以在其余的交互中调用不带查询参数的/ api / person。这是因为身份验证在Spring中存储为会话范围的数据。

希望有帮助。让我知道是否有任何丢失。