Pac4j文档翻译(3.0)

4 篇文章 0 订阅
2 篇文章 0 订阅

Pac4j官方文档传送门:http://www.pac4j.org/docs/index.html

翻译有很多不准确的地方,只作为自己学习的笔记来用。欢迎批评指正。

Pac4j简介

pac4j是一个简单而强大的安全引擎,用于Java对用户进行身份验证、获取其配置文件和管理授权,以确保web应用程序安全。它提供了一套完整的概念和组件。它基于Java 8,并在Apache 2许可下使用。它可用于大多数框架/工具和支持大多数认证/授权机制。

1. 主要概念和组件介绍

  • 1) client(客户端): 客户端表示身份验证机制(流)。它执行登录过程并返回一个用户概要文件。间接客户端用于UI身份验证,而直接客户端则用于web服务身份验证。

  • 2) authenticator(认证器):HTTP客户端验证凭证需要一个认证器。它是ProfileService的一个子组件,该组件验证凭证,同时也处理用户的创建、更新和移除操作。

  • 3) authorizer(授权器):授权器用于检查已认证用户的授权或当前web上下文中的授权。

  • 4) matcher(匹配器):一个匹配器定义了security是否必须应用到安全过滤器。

  • 5) config(配置):配置通过客户端、授权器和匹配器定义安全配置。

  • 6) user profile(用户概要文件):用户概要是已认证用户的概要。它有一个标识符、属性、角色、权限、一个“记住-我”属性和一个链接标识符。

  • 7) web context(web上下文):web上下文是对pac4j实现特有的HTTP请求和响应的抽象,而关联的SessionStore表示会话的实现。

  • 8) security filter(安全过滤器):(或者不论使用什么原理去拦截的HTTP请求)根据客户端和授权配置,通过检查用户已认证和已授权来保护一个URL。如果用户没有被认证,它对直接客户端展示认证,对间接客户端启动登录进程。

  • 9) callback controller(回调控制器):对间接客户端结束登录进程后的回调。

  • 10) logout controller(退出登录控制器):处理应用程序和/或身份服务器注销。

2 认证机制

client支持多种认证机制:OAuth、SAML、CAS、OpenID Connect、HTTP、OpenID、Google APP Engine、Kerberos(SPNEGO)

Authenticators:LDAP、SQL、JWT、MongoDB、CouchDB、IP address、REST API

3 授权机制 Authorizers

通常,授权器被定义在应用的安全配置文件中。有不同的授权器变量如下:

Roles/permissions - Anonymous/remember-me/(fully) authenticated - Profile type, attribute

CORS - CSRF - Security headers - IP address, HTTP method

大多数pac4j组件实现DefaultAuthorizationChecker组件来使用pac4j的逻辑和授权。因此,下列授权器可以通过短名称自动找到:

  • hsts:StrictTransportSecurityHeader 认证器
  • nosniff: XContentTypeOptionsHeader 认证器
  • noframe: XFrameOptionsHeader 认证器
  • xssprotection: XSSProtectionHeader 认证器
  • nocache: CacheControlHeader 认证器
  • securityheaders: as a shortcut for hsts,nosniff,noframe,xssprotection,nocache
  • csrfToken: CsrfTokenGeneratorAuthorizer 认证器
  • csrfCheck: CsrfAuthorizer 认证器
  • csrf as a shortcut for csrfToken,csrfCheck
  • isAnonymous:IsAnonymousAuthorizer 认证器
  • isAuthenticated:IsAuthenticatedAuthorizer 认证器
  • isFullyAuthenticated:IsFullyAuthenticatedAuthorizer 认证器
  • isRemembered: IsRememberedAuthorizer 认证器
  • allowAjaxRequests for a default configuration of the CorsAuthorizer authorizer with the Access-Control-Allow-Origin header set to *.

这些短名称都作为常量定义在DefaultAuthorizers类中。

4 Matchers 匹配器

1) 定义(definition)

pac4j提供了一个安全模型和引擎(特定的行为)。安全过滤器负责url保护、请求认证和可选授权。

在某些情况下,你可能想要绕开安全过滤器(security filter)。而使用匹配器参数(matchers parameter)可以做到,参数通常是一个匹配名称的列表。一个匹配器通常定义在安全配置文件中(security configuration)。

2) 实现(implementation)

一个匹配器可以通过实现Matcher接口来定义。它只有一个方法:

boolean matches(WebContext context);

这个方法表明安全过滤器(security filter)是否必须被应用。

一些默认的matcher匹配器可以用。(但是你可以开发自己的匹配器):
- PathMatcher:允许你从安全检查中排除一些路径。
- HeaderMatcher:允许你检查一个给出的头部是否是空或匹配一个特定的表达式。
- HttpMethodMatcher:允许你检查HTTP请求的方法是否是你预期的已定义的方法之一。

5 Security configuration 安全配置

1) 配置组件
大多数pac4j实现中,安全配置可以通过配置对象去定义。

它有这些必须的:
- PasswordEncoders:密码加密器
- Authenticators:认证器
- Clients:客户端
- Authorizers:授权器
- Matchers:匹配器

例如:

Config 1

FacebookClient facebookClient = new FacebookClient("145278422258960", "be21409ba8f39b5dae2a7de525484da8");
TwitterClient twitterClient = new TwitterClient("CoxUiYwQOSFDReZYdjigBA", "2kAzunH5Btc4gRSaMr7D7MkyoJ5u1VzbOOzE8rBofs");
ParameterClient parameterClient = new ParameterClient("token", new JwtAuthenticator(salt));

Config config = new Config("http://localhost:8080/callback", facebookClient, twitterClient, parameterClient);

config.addAuthorizer("admin", new RequireAnyRoleAuthorizer<>("ROLE_ADMIN"));
config.addAuthorizer("custom", new CustomAuthorizer());

config.addMatcher("excludedPath", new ExcludedPathMatcher("^/facebook/notprotected\\.jsp$"));

您还可以使用一个中间客户端对象来构建Config 1。例如Config 2

Config 2

Clients clients = new Clients("http://localhost:8080/callback", facebookClient, twitterClient, parameterClient);

Config config = new Config(clients);

在上面的例子中,你可以为所有的客户端定义这些内容:

  • 一个回调地址(callback URL)和一个回调地址解析器(CallbackUrlResolver):
clients.setCallbackUrl(callbackUrl); 

clients.setCallbackUrlResolver(callbackUrlResolver);
  • 一个异步请求解析器(AjaxRequestResolver):
clients.setAjaxRequestResolver(ajaxRequestResolver);
  • 一个认证生成器(AuthorizationGenerator):
clients.addAuthorizationGenerator(authorizationGenerator);

2) pac4j-config module(pac4j配置模块)
pac4j-config模块收集所有pac4j工具来定义这个配置对象。当前,只有一个组件允许你从一系列属性中创建客户端:PropertiesConfigFactory. Dropwizard, CAS 和 Knox用到该类。

注意:当需要的时候,这些依赖必须被明确声明。(如果你想要使用SAML、OAuth…)

例如:

pac4j:
  callbackUrl: /callback
  clientsProperties:
    facebook.id: 145278422258960
    facebook.secret: be21409ba8f39b5dae2a7de525484da8
    saml.keystorePath: resource:samlKeystore.jks
    saml.keystorePassword: pac4j-demo-passwd
    saml.privateKeyPassword: pac4j-demo-passwd
    saml.identityProviderMetadataPath: resource:metadata-okta.xml
    saml.maximumAuthenticationLifetime: 3600
    saml.serviceProviderEntityId: http://localhost:8080/callback?client_name=SAML2Client
    saml.serviceProviderMetadataPath: sp-metadata.xml
    anonymous: fakevalue
    ldap.type: direct
    ldap.url: ldap://ldap.jumpcloud.com:389
    ldap.useStartTls: false
    ldap.useSsl: false
    ldap.dnFormat: uid=%s,ou=Users,o=58e69adc0914b437324e7632,dc=jumpcloud,dc=com
    ldap.usersDn: ou=Users,o=58e69adc0914b437324e7632,dc=jumpcloud,dc=com
    ldap.principalAttributeId: uid
    ldap.principalAttributes: firstName,lastName
    ldap.enhanceWithEntryResolver: false
    formClient.loginUrl: /login.html
    formClient.authenticator: ldap

下面是一项你可以来定义客户端(,密码加密器和认证器)的一些属性:

可用属性用法
encoder.spring.type (bcrypt, noop, pbkdf2, scrypt or standard), encoder.spring.bcrypt.length, encoder.spring.pbkdf2.secret, encoder.spring.pbkdf2.iterations, encoder.spring.pbkdf2.hashWidth, encoder.spring.scrypt.cpuCost, encoder.spring.scrypt.memoryCost, encoder.spring.scrypt.parallelization, encoder.spring.scrypt.keyLength, encoder.spring.scrypt.saltLength and encoder.spring.standard.secret根据所提供的属性和命名的编码器定义一个SpringPasswordEncoder。
encoder.shiro (if no specific properties are required), encoder.shiro.generatePublicSalt, encoder.shiro.hashAlgorithmName, encoder.shiro.hashIterations and encoder.shiro.privateSalt根据所提供的属性和命名的编码器定义一个ShiroPasswordEncoder。
ldap.type, ldap.dnFormat, ldap.principalAttributes,ldap.principalAttributeId, ldap.principalAttributePassword, ldap.subtreeSearch, ldap.usersDn, ldap.userFilter, ldap.enhanceWithEntryResolver, ldap.trustCertificates, ldap.keystore, ldap.keystorePassword, ldap.keystoreType, ldap.minPoolSize, ldap.maxPoolSize, ldap.poolPassivator, ldap.validateOnCheckout, ldap.validatePeriodically, ldap.validatePeriod, ldap.failFast, ldap.idleTime, ldap.prunePeriod, ldap.blockWaitTime, ldap.url, ldap.useSsl, ldap.useStartTls, ldap.connectTimeout, ldap.providerClass, ldap.allowMultipleDns, ldap.bindDn, ldap.bindCredential, ldap.saslRealm, ldap.saslMechanism, ldap.saslAuthorizationId, ldap.saslSecurityStrength and ldap.saslQualityOfProtection根据所提供的属性和命名ldap或ldap来定义LdapAuthenticator。
db.dataSourceClassName, db.jdbcUrl, db.userAttributes, db.userIdAttribute, db.usernameAttribute, db.userPasswordAttribute, db.usersTable, db.username, db.password, db.autoCommit, db.connectionTimeout, db.idleTimeout, db.maxLifetime, db.connectionTestQuery, db.minimumIdle, db.maximumPoolSize, db.poolName, db.initializationFailTimeout, db.isolateInternalQueries, db.allowPoolSuspension, db.readOnly, db.registerMbeans, db.catalog, db.connectionInitSql, db.driverClassName, db.transactionIsolation, db.validationTimeout, db.leakDetectionThreshold, db.customParamKey, db.customParamValue, db.loginTimeout, db.dataSourceJndi and db.passwordEncoder要基于所提供的属性定义DbAuthenticator,并命名为db或db.N
rest.url按照所提供的属性和命名rest或rest.n来定义RestAuthenticator
anonymous定义AnonymousClient,该值将被忽略
directBasicAuth.authenticator根据所提供的属性定义DirectBasicAuthClient
saml.keystorePassword, saml.privateKeyPassword, saml.keystorePath, saml.identityProviderMetadataPath, saml.maximumAuthenticationLifetime, saml.serviceProviderEntityId, saml.serviceProviderMetadataPath, saml.destinationBindingType, saml.keystoreAlias根据所提供的属性定义SAML2Client
cas.loginUrl, cas.protocol根据所提供的属性来定义CasClient
oidc.type (google or azure), oidc.id, oidc.secret, oidc.scope, oidc.discoveryUri, oidc.useNonce, oidc.preferredJwsAlgorithm, oidc.maxClockSkew, oidc.clientAuthenticationMethod, oidc.customParamKey1, oidc.customParamValue1, oidc.customParamKey2,oidc.customParamValue2根据所提供的属性定义OpenID connect client
formClient.authenticator, formClient.loginUrl, formClient.usernameParameter formClient.passwordParameter根据所提供的属性定义FormClient
indirectBasicAuth.authenticator, indirectBasicAuth.realName根据所提供的属性定义IndirectBasicAuthClient
facebook.id, facebook.secret, facebook.scope, facebook.fields基于所提供的属性定义一个FacebookClient
twitter.id, twitter.secret根据所提供的属性来定义TwitterClient
github.id, github.secret根据所提供的属性来定义GitHubClient
dropbox.id, dropbox.secret根据所提供的属性来定义DropBoxClient
windowslive.id, windowslive.secret根据所提供的属性定义windowslivecent
yahoo.id, yahoo.secret根据所提供的属性来定义一个YahooClient
linkedin.id, linkedin.secret, linkedin.fields, linkedin.scope根据所提供的属性来定义一个LinkedIn2Client
foursquare.id, foursquare.secret根据所提供的属性来定义一个FoursquareClient
google.id, google.secret, google.scope根据所提供的属性定义一个Google2Client

注意:
- 你可以在属性末尾添加一个数字来定义多个相同类型的client:cas.loginUrl.2, oidc.type.5
- passwordEncoder属性必须设置为已定义的passwordEncoder的名称,如:encoder.spring or encoder.shiro.3
- Authenticator属性必须设置为已定义的 身份验证器( Authenticator)的名称,如: ldap or db.1或者隐含的值:testUsernamePassword or testToken.

6 User profile 用户概要

当用户成功通过pac4j进行身份验证时,他的数据将从身份提供程序中检索,并构建一个用户概要。他的概要有:

  • an identifier (getId()):标识符
  • attributes (getAttributes(), getAttribute(name)):属性
  • authentication-related attributes (getAuthenticationAttributes(), getAuthenticationAttribute(name)):认证相关属性
  • roles (getRoles()):角色
  • permissions (getPermissions()):权限
  • a client name (getClientName()):客户端名称
  • a remember-me nature (isRemembered()):记住我的性质
  • a linked identifier (getLinkedId()):链接标识符

1) Identifier

每个用户配置文件必须具有唯一的标识符。因此,当构建用户概要文件时,pac4j客户端使用的是概要标识符——从身份提供者那里执行惟一性的值。

这可以很好地处理来自同一身份提供者的概要文件,尽管在使用多个身份提供者时这可能会成为一个问题。我们可能在标识提供者中选择的标识符之间发生冲突。为了避免这个问题,在文件标识符之前添加概要文件类名,要有一个”类型标识符”。

例如:

profile.getId() // 00001
profile.getTypedId() // org.pac4j.oauth.profile.facebook.FacebookProfile#00001

2) 属性

用户概要文件具有属性,这些属性来自于从身份提供者检索的数据(在转换之后)。

3) 认证相关属性

一些身份提供者将包括与身份验证本身相关的属性,比如身份验证方法、身份验证有效的时间期限,或关于身份提供者的元数据。这些属性与用户的属性是分开存储的。

4) 角色和权限
角色和权限可以通过addRole(role), addRoles(roles), addPermission(permission) and addPermissions(permissions) 方法添加到用户概要文件中。

它们通常是在一个授权生成器(AuthorizationGenerator)中计算的。

5) 客户端名称

在登录过程中,客户端的名称通过setClientName(name)保存到用户概要中,随后可以通过getClientName()方法检索到。

6) 记住我
用户概要可以通过setRemembered(boolean)方法定义为记住我,而不是完全通过认证。isRemember()方法人会用户概要是否被记住。

7) CommonProfile的通用方法

MethodTypeReturns
getEmail()StringEmail 属性
getFirstName()Stringfirst_name 属性
getFamilyName()Stringfamily_name 属性
getDisplayName()Stringdisplay_name 属性
getUsername()Stringusername 属性
getGender()Gendergender 属性
getLocale()Localelocale 属性
getPictureUrl()URIpicture_url 属性
getProfileUrl()URIprofile_url 属性
getLocation()Stringlocation 属性
asPrincipal()Principal一个包含当前已认证用户名的对象
isExpired()boolean如果当前配置文件过期,则为false

8) 配置文件定义(Profile definition)

配置文件类和属性通过实现 ProfileDefinition类来定义。

setProfileFactory方法允许您定义实例类,以便返回给用户配置文件,而primary 和 secondary方法允许您用特定的转换器定义属性。

许多属性转换器以及存在: BooleanConverter, ColorConverter… 查看包 org.pac4j.core.profile.converter

因此,newProfile方法返回一个新的类实例,而convertAndAdd方法如果有相关的转换器会转换属性,并将它们添加到概要文件中。

9) 配置层级(Profile hierarchy)

事实上,大多数Client都不会返回一个CommonProfile,而是一个特定的配置,如:FacebookProfile, the OidcProfile…:
- (部分地)用特定的实现覆盖公共概要的公共方法
- 为他们的特定属性添加特定的getter。

10) 链接标识符
每个用户配置文件可能有一个链接标识符,它是另一个用户配置文件的标识符。这种方式,使得两个用户配置文件都被联系起来,它允许你通过一个帐户进行身份验证,这个用户可以加载定义在第一个用户中的链接用户,特别是通过使用LoadLinkedUserAuthorizationGenerator生成的。

7 会话存储和存储(SessionStore and Store)

  1. Session Store

WebContext对于处理HTTP请求和响应是一个抽象的类。为了处理session,它依赖于一个SessionStore,可以通过getSessionStore方法获得。

SessionStore有如下方法:
- getOrCreateSessionId: 获取或创建会话标识符并在必要时用它初始化会话
- get: 从会话中获取属性
- set: 给会话设置属性
- destroySession: 销毁潜在的web会话
- getTrackableSession: 把本机会话作为可跟踪对象(用于反向通道注销)
- buildFromTrackableSession: 从可跟踪的会话(用于反向通道注销)构建一个新的会话
- renewSession: 通过将所有数据复制到一个新的数据来更新本机会话

例如,J2EContext当前使用J2ESessionStore,依赖于J2ESession。在游戏中,我们有一个特定的基于缓存的PlayCacheSessionStore,以及在Knox中有一个基于cookie的KnoxSessionStore。

ProfileStorageDecision定义与该概要文件相关的决策,通过该决策,我们判断是否必须将其读取并保存到web会话中。它被DefaultSecurityLogic使用:
- DefaultProfileStorageDecision在默认情况下被设置,这对于一个只使用间接客户端或直接客户端的web应用程序是适合的。

  1. Store

在某些情况下,需要一个缓存机制。在pac4j中,通过Store这个概念定义。

它有如下几个方法:
- get:从store中获取一个值
- set:往store中设置一个值
- remove:从store中移除一个值(通过key)

它只有一个使用了Guava的默认实现:GuavaStore。如果需要,你可以提供你自己的一个Store。

8 发布说明-向后兼容性(Release notes - Backward compatibility)

此处略去。。。

9 认证流程-大图片(Authentication flows - Big picture)

认证流程直接参考官网即可。。。
1. Authentication flows:
地址:http://www.pac4j.org/docs/authentication-flows.html

1) UI 认证(有状态stateful/间接客户端indirect client):
image
CAS特定的有状态身份验证流:
image

2) Web服务认证(无状态stateless/直接客户端direct client):
image

  1. Big picture:
    image

10 自定义(customizations)

pac4j为各种需求提供了大量的组件,所以在进行定制之前,您应该仔细阅读Clients, Authenticators 和 Authorizers页面,以检查已经提供的内容。

自定义认证器/授权器组件

确定你清楚的明白不同组件的角色是什么:
- Client是一个完整的登录过程:间接地用于UI(IndirectClient),直接的用于web服务(DirectClient。它重定向到身份提供者(仅间接客户端)),提取用户凭证,验证用户凭证,并为经过身份验证的用户创建用户配置文件。
- RedirectActionBuilder会将用户重定向到身份提供程序以便登录(间接客户端)
- CredentialsExtractor从HTTP请求中提取用户凭证(间接和直接的客户端)
- Authenticator验证用户凭证(间接和直接客户端)
- ProfileCreator为经过身份验证的用户(间接和直接客户端)创建用户配置文件。
- Authorizer允许基于用户配置文件或web上下文访问
- Matcher定义了安全性是否必须应用于web上下文
- 一个AuthorizationGenerator为给定的用户概要文件生成适当的角色和权限。

重写或创建新组件应该是简单的。尽管如此,建立客户端需要额外的努力,需要注意:
- 你需要了解你希望支持哪种身份验证机制:它是用于UI(凭证只提供一次,身份验证几乎总是在外部身份提供程序中发生)或web服务(为每个请求传递凭证)
- 所有客户端都应该实现IndirectClient接口,并定义适当的RedirectActionBuilder, CredentialsExtractor,Authenticator和ProfileCreator (以及可选的LogoutActionBuilder)。
- 它可能需要创建一个新的Credentials类型(如果它不是一个由TokenCredentials设计或UsernamePasswordCredentials设计的用户名/密码的简单的字符串)。这些新的凭证可能继承受支持协议的基本凭证(如oauth凭据)
- 为新客户端创建新概要通常是一种良好的实践。(不管这个配置文件是否有特定的数据),以便能够区分所有用户配置文件。新的用户配置文件应该从协议支持的基本概要文件继承,比如OAuth20Profile。至少,它必须继承自CommonProfile。身份提供者返回的数据可能需要被转换(例如,一个单一的字符串到Java枚举中),对于这一点,转换器(类继承了AttributeConverter的类)是必要的。转换器和返回的用户概要类都必须在ProfileDefinition中定义。

改变核心流:
覆盖或创建新组件允许你在常规pac4j“过滤器”的定义逻辑的边界内实现新的行为。然而,在某些情况下,这可能还不够。因此,你可能决定打破流程,通过请求一些额外的操作来改变所提供的行为。这可以通过抛出HttpAction(如任何异常)来实现,因为大多数组件都允许这样做。

例如:

public class ExampleAuthorizer implements Authorizer<CommonProfile> {

    @Override
    public boolean isAuthorized(WebContext context, List<CommonProfile> profiles) throws HttpAction {
        if ("specificValue".equals(context.getRequestHeader("specificHeader")))
        {
            throw HttpAction.redirect("force redirection", context, "/message.html");
        }
        return true;
    }
}

自定义web集成

pac4j实现严重依赖于WebContext和SessionStore来处理HTTP请求、响应和会话。这些组件的默认实现可能会被覆盖或替换。除了默认的ProfileManager(用于保存/恢复概要文件)或GuavaStore(在缓存中保存数据)。在所有情况下,没有什么比查看现有组件作为示例更好的了。请不要犹豫,在pac4j dev邮件列表上问任何问题。

11 第三方扩展

对于由第三方开发的pac4j,有一些扩展。扩展提供了核心pac4j发行版中不可用的特性,这些特性可能对特定的用户有特定的需求是有用的。目前,以下扩展名是已知的:

IDC 扩展

IDC Extensions to PAC4J是IDC内部开发的一个项目,并以开源的形式发布。它提供了如下模块:
- SAML客户端的数据库配置-这个模块允许你使用关系数据库配置一系列SAML2客户端,例如Oracle数据库。你不需要改变你的PAC4J静态配置(例如spring xml file)就能使应用的配置发生改变。你只需向数据库表中添加一行或修改现有行,然后重新启动你的应用程序即可。你也可以实现一个重新加载机制,允许你在不重启应用程序的情况下进行配置更改。

12 JavaDoc

官方链接地址:http://www.pac4j.org/apidocs/pac4j/2.3.1/index.html

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值