CAS通过用户属性控制访问权限

前文

使用CAS作单点登录的时候需要控制不同的用户登录不同的服务

用户保存数据库

修改cas.properties

cas.authn.jdbc.query[0].user=root
cas.authn.jdbc.query[0].password=admin
cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver
cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/cas?serverTimezone=UTC

cas.authn.jdbc.query[0].sql=SELECT * FROM Users WHERE userid=?
cas.authn.jdbc.query[0].field-password=password
cas.authn.jdbc.query[0].fieldExpired=expired
cas.authn.jdbc.query[0].fieldDisabled=disabled

数据库结构示例:

CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`userid` varchar(255) NOT NULL DEFAULT '',
`password` varchar(255) NOT NULL DEFAULT '',
`email` varchar(255) NOT NULL DEFAULT '',
`phone` varchar(255) DEFAULT NULL,
`firstName` varchar(255) DEFAULT NULL,
`lastName` varchar(255) DEFAULT NULL,
`expired` int(11) NOT NULL DEFAULT '0',
`disabled` int(11) NOT NULL DEFAULT '0',
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4

用户属性保存数据库

# 释放属性的策略, 很重要!
cas.authn.authentication-attribute-release.enabled=true

cas.authn.attribute-repository.jdbc[0].user=${cas.authn.jdbc.query[0].user}
cas.authn.attribute-repository.jdbc[0].password=${cas.authn.jdbc.query[0].password}
cas.authn.attribute-repository.jdbc[0].driverClass=${cas.authn.jdbc.query[0].driverClass}
cas.authn.attribute-repository.jdbc[0].dialect=${cas.authn.jdbc.query[0].dialect}
cas.authn.attribute-repository.jdbc[0].url=${cas.authn.jdbc.query[0].url}

cas.authn.attribute-repository.jdbc[0].sql=SELECT * FROM UserAttribute WHERE {0}
cas.authn.attribute-repository.jdbc[0].username=uid
cas.authn.attribute-repository.jdbc[0].attributes.uid=uid
cas.authn.attribute-repository.jdbc[0].attributes.role=role
# cas.authn.attribute-repository.jdbc[0].attributes.display-name=displayName
# cas.authn.attribute-repository.jdbc[0].attributes.cn=commonName
# cas.authn.attribute-repository.jdbc[0].attributes.affiliation=groupMembership

cas.authn.attribute-repository.jdbc[0].single-row=false
# cas.authn.attribute-repository.jdbc[0].order=0
# cas.authn.attribute-repository.jdbc[0].id=
# cas.authn.attribute-repository.jdbc[0].require-all-attributes=true
# cas.authn.attribute-repository.jdbc[0].case-canonicalization=NONE|LOWER|UPPER
# cas.authn.attribute-repository.jdbc[0].query-type=OR|AND
# cas.authn.attribute-repository.jdbc[0].case-insensitive-query-attributes=username

# Used only when there is a mapping of many rows to one user
cas.authn.attribute-repository.jdbc[0].column-mappings.attribute=value
# cas.authn.attribute-repository.jdbc[0].column-mappings.column-attr-name2=columnAttrValue2
# cas.authn.attribute-repository.jdbc[0].column-mappings.column-attr-name3=columnAttrValue3

数据库示例:

CREATE TABLE `userattribute` (
`uid` varchar(255) DEFAULT NULL,
`attribute` varchar(255) DEFAULT NULL,
`value` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

服务保存到redis

# cas.service-registry.init-from-json=true
# cas.service-registry.json.location=file:/etc/cas/services
cas.service-registry.redis.host=localhost
cas.service-registry.redis.database=1
cas.service-registry.redis.port=6379

释放属性的策略

[POST]https://example.cas.com:8443/cas/v1/services

Basic Auth: username:password

body:

{
"@class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId" : "http://sso.bdzh.com:8000.+",
"name" : "Django SSO",
"id" : 1,
"attributeReleasePolicy" : { // 服务器返回所有的属性
"@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
},
"accessStrategy" : {
"@class" : "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy",
"enabled" : true,
"ssoEnabled" : true,
"requireAllAttributes": false,
"requiredAttributes" : {
"@class" : "java.util.HashMap",
"role" : [ "java.util.HashSet", [ "ROLE_ADMIN" ] ] // 限制用户属性role必须包含ROLE_ADMIN
}
}
}

修改服务的权限和用户属性

在用户数属性表userattribute中加入数据

例如:

mysql> select * from userattribute;
+---------+--------------+------------+
| uid | attribute | value |
+---------+--------------+------------+
| casuser | role | ROLE_ADMIN |
| casuser | role | ROLE_OTHER |
| test | role | ROLE_ADMIN |
| test | display-name | 测试名称 |
+---------+--------------+------------+

这样,用户testcasuser就都可以访问Django SSO服务了