1. Authelia配置
./data/authelia/config/configuration.yml
--- ############################################################### # Authelia configuration # ############################################################### server: address: 'tcp://:9091' log: level: 'debug' # 基于时间的一次性密码配置 totp: # 是否关闭 disable: true # 身份验证器应用程序中显示的发行者名称 issuer: 'authelia.com' # 访问控制(https://www.authelia.com/configuration/security/access-control/) # deny - 拒绝; bypass - 无需认证; one_factor - 用户名密码认证; two_factor - 二次认证 access_control: # 默认策略 default_policy: 'deny' # 规则 rules: - domain: 'public.example.cn' policy: 'bypass' - domain: 'traefik.example.cn' policy: 'one_factor' - domain: 'secure.example.cn' policy: 'two_factor' # 身份验证方式配置 identity_providers: # OIDC配置 oidc: # 【需要修改】64位随机字符串,可以使用命令(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1 | tr -d '\n' ; echo)生成 hmac_secret: 'nIrX4RIilsAIfxddUeamyizomGvRWL8rocVeJyCMD22jU4PTgdSFdMAnfqTC5lEL' jwks: - key_id: 'jwt_key' algorithm: 'RS256' use: 'sig' # 【需要修改】JWT加密key,可以使用命令(docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:4.39.3 authelia crypto pair rsa generate --directory /keys)生成到当前文件夹下,使用命令(cat ./private.pem)打印获取 key: | -----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDa7Bwk5EQJTkde 9wrGGGFIgLM88Izc3wxAw6wstFlupeKBXifSuqSZm0y2TIdjf0578qyoTEU6bnCu GuwlEVTPovjgCLJ9jS1MynJ+vtb7cUe58PKyHygUF3M7WOMJKh36cGczMLdz/UE5 rO0UcScomw0wsxri8+ggtJe4juzS75WdrKpvOM/6JAj0NZsCEdZLxM04JcrApxFo WmxyB+SldJzBkaK98xUKdphspptIvJJ/w3SEefTNagbVRzOHp8kCUkKMkUEFAVMH fZ68CJjC01rgIluyDmAMCDvwceHiRfDGlQYAwQtSz3YSexN22CJoCRJV5TdowFLL wYORnsGFAgMBAAECggEAIfcwBqlDxQ3YFOvPSBzQOyd8p5/KuxoAFKxHMkho97nV Aq1REGjU0OA/bqlA+DbwPlrQXuw2cXJhGSIkMTwXJH/sjRXMW55jwN5IFVIWmLxi nH69qNUcqsFYp4SK9QkLzadS26ZbUCuiywgBYIKNyMcFrOCc80lUYn6ia4gBRliM FEMwEXpknGJOEp8+AeAJUTnjGLmOCL6a7r6rcOCm+Odz7yqKyY9MnsAjh3vZ2th/ QzwOdWjim9iNSMbEj/C5BqcQ1GmQW1hbdUPJBcvq8VwLsKiAErJYUIzf+lZjlLxh VJUXaemBCYXFOjqxxuTBbB7+3I0E5fcuO9yotSBKoQKBgQD6Az8xZmrxq18wZL5T Dwh3X5ce/VxoZ9NeDV1AY4DOJdjCo/moIKzPSYTsFSQbrA5qMxeTPpT7T6tGIHFi 0+ZkPRgToeVEv4CedJ4SxWrVy7qt+TDa3kl19merFFtnkrrDcaDWdA16UXKN+OsK kJgHDkpK51roT0Mt0BzjT0YZKwKBgQDgKkHbnGFaaS6HEHCeVCsg2sal5+MyWh68 fGI6XmMJxSMU9sI6KJobgWDMLNM7kPBeyhH0knL4+CBpQiCbj5GiN9SuunkbxS7C VHQImaOVg4JKsan7aMGdrMKXhrp7pFdCqGFAsfC5As2HnxqCHKt0Jy3ivDBw3MKG /v6LRFXYDwKBgQCLxYrrtEVvrI5AAOKCjvH9wtw6wAyMdhcuCqyqlbZqCbCgSIoH m5ThIkoErmEMc2lvp/azJBaoVUb8oqChTrQMMDeoqicCA0oFzE6fUe1Db22DW8Ab bJCHOWWFuJDNW7O8FmeD3Ue3rZcslg/ZTTMhJrUUITmqjL2S/DlaP3SCFwKBgQDR eWuVhyrKS+P4vvoeWlT7HLXpLyp2URTL2ggIt08hQCEqY/TYWDy6W0pTQcgar7SP P5FL1NavpV7UPcEu3RigWD/dD9BAjSDG5BiSONBO1VeZ6TAJCbl0WI52/qWhCM+q MKLAzAdBPEdH5vvkfloR7tLIQEecEA+QCxVemvsFLQKBgQDoxfWf1n2OKdb49QBi 963yXiU2y3f82h+Pj4u10T7IeDKIbSKP9VDxG3Hs9DQr6CQChKrJ+t8Sy2PFhkNV YnQAOd/OFzCJN1NjfZa3z+BfoIdaGU8hZWLAt+RFXpLtKoPI2gHt+BXhlMESmX8U f8pO3iWLcEcFoyg1xltkjLLuWw== -----END PRIVATE KEY----- lifespans: access_token: '1h' authorize_code: '1m' id_token: '1h' refresh_token: '90m' claims_policies: default: id_token: ['rat', 'email', 'preferred_username', 'name', 'ext_role', 'ext_mobile', 'ext_address', 'ext_description', 'ext_department'] custom_claims: ext_role: attribute: 'role' ext_mobile: attribute: 'phone_number' ext_address: attribute: 'street_address' ext_description: attribute: 'description' ext_department: attribute: 'department' scopes: extend: claims: ['ext_role', 'ext_mobile', 'ext_address', 'ext_description', 'ext_department'] clients: - client_id: 'example_client_id' client_name: 'example_client_name' # 【需要修改】42位及以上随机字符串 client_secret: 'PeqqizzHMN04CigGEgin8kbK6YgKgrkHilGtbaWC63' authorization_policy: 'one_factor' token_endpoint_auth_method: 'client_secret_post' claims_policy: 'default' scopes: ['openid', 'profile', 'email', 'extend'] redirect_uris: ['http://localhost:8080/test/callback', 'http://localhost:5173/cdzmiot/admin/dev-api/oauth2/authelia/callback'] # 会话配置 session: # 【需要修改】21位及以上随机字符串 secret: Li3KiigbUH4xd3BLNotqB cookies: - name: 'authelia_session' # 【需要修改】对应的域名 domain: 'example.cn' # 【需要修改】对应的认证接口路径 authelia_url: 'https://auth.example.cn' expiration: '1 hour' inactivity: '5 minutes' default_redirection_url: 'https://public.example.cn' # 身份认证后端配置 authentication_backend: password_reset: # 是否关闭密码重置 disable: true ldap: address: ldap://go-ldap-admin-openldap:389 implementation: custom timeout: 5s base_dn: DC=eryajf,DC=net additional_users_dn: OU=people users_filter: (&({username_attribute}={input})(objectClass=person)) additional_groups_dn: '' groups_filter: (&(uniqueMember={dn})(objectclass=groupOfUniqueNames)) user: CN=admin,DC=eryajf,DC=net password: '123456' attributes: nickname: givenName username: uid phone_number: mobile street_address: postalAddress group_name: businessCategory extra: departmentNumber: name: role multi_valued: false value_type: string description: name: description multi_valued: false value_type: string businessCategory: name: department multi_valued: false value_type: string # 存储配置 storage: # 【需要修改】21位及以上随机字符串 encryption_key: 'nVeh1F9W8vg5jHF3YXYqb' # 【需要修改】MYSQL配置 mysql: address: 'tcp://172.18.0.1:3306' database: 'YOUR_MYSQL_DATABASE' username: 'YOUR_MYSQL_USERNAME' password: 'YOUR_MYSQL_PASSWORD' timeout: '5s' # 登录尝试规则,当前配置:2分钟最大重试3次,封禁5分钟 regulation: max_retries: 3 find_time: '2 minutes' ban_time: '5 minutes' # 通知 notifier: filesystem: filename: '/config/notification.txt' ...
2. docker-compose部署文件
./docker-compose.yml
networks: oidc-network: external: true services: # OIDC服务 authelia: image: authelia/authelia:4.39.3 container_name: authelia hostname: authelia restart: always healthcheck: disable: true environment: TZ: Asia/Shanghai ports: - 39443:9091 volumes: - ./data/authelia/config:/config depends_on: - openldap networks: - oidc-network # ldap管理工具 go-ldap-admin: image: registry.cn-hangzhou.aliyuncs.com/eryajf/go-ldap-admin container_name: go-ldap-admin hostname: go-ldap-admin restart: always environment: WAIT_HOSTS: openldap:389 DB_DRIVER: mysql # 请修改下面的 MySql 配置,需自行创建数据库和用户 MYSQL_HOST: YOUR_MYSQL_HOST MYSQL_PORT: YOUR_MYSQL_PORT MYSQL_USERNAME: YOUR_MYSQL_USERNAME MYSQL_PASSWORD: YOUR_MYSQL_PASSWORD MYSQL_DATABASE: YOUR_MYSQL_DATABASE ports: - 39888:8888 volumes: - ./data/go-ldap-admin:/app/data depends_on: - openldap links: - openldap:go-ldap-admin-openldap networks: - oidc-network # ldap服务 openldap: image: registry.cn-hangzhou.aliyuncs.com/eryajf/openldap:1.4.1 container_name: go-ldap-admin-openldap hostname: go-ldap-admin-openldap restart: always environment: TZ: Asia/Shanghai LDAP_ORGANISATION: "eryajf.net" LDAP_DOMAIN: "eryajf.net" LDAP_ADMIN_PASSWORD: "123456" command: [ '--copy-service' ] volumes: - ./data/openldap/database:/var/lib/ldap - ./data/openldap/config:/etc/ldap/slapd.d ports: - 39389:389 networks: - oidc-network
3. SpringBoot集成
pom.xml
<!-- spring security 安全认证 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- spring security 集成 OAuth2 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> </dependency>application.yaml
spring: security: oauth2: # 与Authelia中的配置保持一致 client: registration: sso: client-id: example_client_id client-secret: PeqqizzHMN04CigGEgin8kbK6YgKgrkHilGtbaWC63 authorization-grant-type: authorization_code redirect-uri: http://localhost:8080/test/callback scope: ['openid', 'profile', 'email', 'extend'] provider: sso: issuer-uri: https://auth.example.cn user-name-attribute: preferred_usernameSpringSecurityConfig.java
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import static org.springframework.security.config.Customizer.withDefaults; @EnableWebSecurity(debug = true) public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin().disable(); http.csrf().and().cors().disable(); http.authorizeRequests() .mvcMatchers("/test/callback") .permitAll() .anyRequest().authenticated(); // 授权码模式回调 http.oauth2Login(withDefaults()); } }TestController.java
import cn.hutool.http.HttpUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class UserController { @Value("${spring.security.oauth2.client.registration.sso.client-id}") private String clientId; @Value("${spring.security.oauth2.client.registration.sso.client-secret}") private String clientSecret; @Value("${spring.security.oauth2.client.registration.sso.authorization-grant-type}") private String grantType; @Value("${spring.security.oauth2.client.registration.sso.redirect-uri}") private String redirectUri; @GetMapping("/test/callback") public String getTokenByCode(String code) { Map<String, Object> paramMap = new HashMap<>(); paramMap.put("code", code); paramMap.put("client_id", clientId); paramMap.put("client_secret", clientSecret); paramMap.put("grant_type", grantType); paramMap.put("redirect_uri", redirectUri); return HttpUtil.post("https://auth.example.cn/api/oidc/token", paramMap); } }