# celery 找不到任务

from celery import Celery
import os


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yourproject.settings')

app = Celery('yourproject')
app.config_from_object('django.conf:settings', namespace='CELERY')

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS, force=False)

如果使用了上述方法还是没有任务,可能是代码错误,但是没有提示。

可以强制查找任务

app = Celery('bdzhserver', include=['your_module.tasks'])

反射

go语言提供了一种机制,能够在运行时更新变量和检查他们的值、调用他们的方法和他们支持的内在操作,而不需要在编译的时候就知道这些变量的具体类型。这种机制被称作反射

阅读全文 »

包和工具

包简介

  • 每个包一般都定义了一个不同的名字空间用于它内部的每个标识符的访问
  • 每个包还通过控制包内名字的可见性和是否导出来实现封装特性
  • 当我们修改了一个源文件,我们必须重新编译该源文件对应的包和所有依赖该包的其他包
阅读全文 »

使用共享变量实现并发

竞态

竞态是指程序在多个goruntine交叉执行操作时,没有给出正确的结果。

三种避免数据竞态的方法:

  • 不要修改变量
  • 避免从多个goruntine访问同一变量
  • 允许多个goruntine访问同一变量,但同一时间只有一个goruntine可以访问。这种叫作互斥机制。
阅读全文 »

接口

接口即约定

接口类型

一个接口类型定义了一套方法,如果一个具体类型要实现该接口,那么必须实现接口类型定义中的所有方法。

例如:

package io

type Reader interface {
Read(p []byte) (n int, err error)
}

type Closer interface {
Close() error
}

type ReadWriter interface {
Reader
Writer
}

type ReadWriterCloser interface {
Reader
Writer
Closer
}
阅读全文 »

方法

方法声明

方法的声明和普通函数的声明类似,只是在函数名字的前面多了一个参数。这个参数把这个方法绑定到了这个参数对应的类型上。

示例:

package geometry

import "math"

type Point struct{X, Y float64}

// 普通的函数
func Distance(p, q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}

// Porint类型的方法
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}

附加参数p成为方法的的接收者.

阅读全文 »

CAS账号密码encode

添加依赖cas-server-support-jdbc

build.gradle 中加入

implementation "org.apereo.cas:cas-server-support-jdbc:${casServerVersion}"
cas.authn.accept.enabled=false
#server.ssl.keyStore=/etc/cas/server.keystore

cas.jdbc.show-sql=true
cas.jdbc.gen-ddl=true
cas.jdbc.case-insensitive=false

# 数据库连接
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].password-encoder.type=DEFAULT
cas.authn.jdbc.query[0].password-encoder.character-encoding=UTF-8
cas.authn.jdbc.query[0].password-encoder.encoding-algorithm=MD5
# cas.authn.jdbc.query[0].password-encoder.secret=test

# 获取盐值区域
# 加密算法
cas.authn.jdbc.encode[0].algorithm-name=MD5
# encode 1次
cas.authn.jdbc.encode[0].number-of-iterations=1
# 盐值字段
cas.authn.jdbc.encode[0].salt-field-name=salt
cas.authn.jdbc.encode[0].password-field-name=password
# cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=select * from users where username=?
cas.authn.jdbc.encode[0].url=jdbc:mysql://localhost:3306/cas?serverTimezone=UTC
cas.authn.jdbc.encode[0].dialect=org.hibernate.dialect.MySQLDialect
cas.authn.jdbc.encode[0].driverClass=com.mysql.cj.jdbc.Driver
cas.authn.jdbc.encode[0].user=root
cas.authn.jdbc.encode[0].password=admin

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

由此,CAS账号的密码加密方式为: MD5(SALT + PASSWORD)

前文

使用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服务了

0%