kylo系统权限是双重权限,auth-kylo(是用于查看页面的,如去掉进入页面,将是白板)
自带支持默认(dladmin,thinkbig)
auth_file(users.properties,group.properties)
对于group.properties(如果使用auth-kylo、auth-file组合,group.properties是一个空文档,因为auth-kylo里面有组的配置,重复了导致登录不上)
auth-simple
auth-ldap(用LDAP库设置登录)
auth-ad (使用Active Directory对用户进行身份验证,并加载任何关联的#用户组)
自定义登录
使用mysql设置用和groups登录kylo(auth-mysql)
SQL语句:
DROP TABLE IF EXISTS `kylo_auth_user`;
CREATE TABLE `kylo_auth_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`user_password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`group_id` int(11) DEFAULT NULL,
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
DROP TABLE IF EXISTS `kylo_auth_group`;
CREATE TABLE `kylo_auth_group` (
`group_id` int(11) NOT NULL,
`group_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`group_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
在security模板中加入security-auth-mysql模板
目录结构
注:对于jpa,在此系统中需要放在包com.thinkbiganalytics.metadata.jpa包中才能扫描到具体的jpa接口对象注入,不然会一直包找不到MysqlDao对象(具体不清楚)
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>kylo-security-auth-mysql</artifactId>
<parent>
<groupId>com.thinkbiganalytics.kylo</groupId>
<artifactId>kylo-security</artifactId>
<version>0.10.0.1-SNAPSHOT</version>
</parent>
<properties>
<plugin.license.parentRelative>../../</plugin.license.parentRelative>
</properties>
<dependencies>
<dependency>
<groupId>com.thinkbiganalytics.kylo</groupId>
<artifactId>kylo-security-auth</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
</dependencies>
</project>
kylo是用来jpa连接数据库,具体jpa的使用(自学)
用户
import javax.persistence.*;
/**
* @author: shudj
* @time: 2019/4/8 16:42
* @description:
*/
@Entity
@Table(name = "kylo_auth_user")
public class User {
@Id //这是一个主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
@Column(name = "user_id",length = 11) //这是和数据表对应的一个列
private Integer id;
@Column(name = "user_name",length = 50) //这是和数据表对应的一个列
private String username;
@Column(name = "user_password",length = 50) //这是和数据表对应的一个列
private String password;
// 多对一关联group表
@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)
@JoinColumn(name="group_id")
private Group group;
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public User() {}
// setter,getter方法
}
用户组
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author: shudj
* @time: 2019/4/10 14:37
* @description:
*/
@Entity
@Table(name = "kylo_auth_group")
public class Group {
@Id
@Column(name = "group_id",length = 11)
private Integer groupId;
@Column(name = "group_name", length = 10)
private String groupName;
// setter,getter方法
}
继承JpaRepository接口
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
/**
* @author: shudj
* @time: 2019/4/8 15:15
* @description:
*/
public interface MysqlAuthDao extends JpaRepository<User,Integer> {
Optional<User> findByUsername(String userName);
}
注:对于jpa使用findBy...,会根据By后面的属性自动生成sql语句
登录设置
import com.thinkbiganalytics.auth.jaas.LoginConfiguration;
import com.thinkbiganalytics.auth.jaas.LoginConfigurationBuilder;
import com.thinkbiganalytics.auth.jaas.config.JaasAuthConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
* @author: shudj
* @time: 2019/4/8 14:13
* @description:
*/
@Configuration
@Profile("auth-mysql")
public class MysqlAuthConfig {
@Value("${security.auth.mysql.login.flag:required}")
private String loginFlag;
@Value("${security.auth.mysql.login.order:#{T(com.thinkbiganalytics.auth.jaas.LoginConfiguration).DEFAULT_ORDER}}")
private int loginOrder;
@Autowired
private AuthenticationService authenticationService;
@Bean(name = "servicesLoginConfiguration")
public LoginConfiguration servicesLoginConfiguration(LoginConfigurationBuilder builder) {
// @formatter:off
return builder
.order(this.loginOrder)
.loginModule(JaasAuthConfig.JAAS_SERVICES)
.moduleClass(MysqlAuthServiceLoginModule.class)
.controlFlag(this.loginFlag)
.option(MysqlAuthServiceLoginModule.AUTH_SERVICE_OPTION, authenticationService)
.add()
.build();
// @formatter:on
}
@Bean(name = "uiServiceLoginConfiguration")
public LoginConfiguration uiServiceLoginConfiguration(LoginConfigurationBuilder builder) {
// @formatter:off
return builder
.order(this.loginOrder)
.loginModule(JaasAuthConfig.JAAS_UI)
.moduleClass(MysqlAuthServiceLoginModule.class)
.controlFlag(this.loginFlag)
.option("authService", authenticationService)
.add()
.build();
// @formatter:on
}
}
具体登录操作实现在dologin方法中
package com.thinkbiganalytics.metadata.auth;
import com.thinkbiganalytics.auth.jaas.AbstractLoginModule;
import com.thinkbiganalytics.security.ServiceAdminPrincipal;
import com.thinkbiganalytics.security.UsernamePrincipal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import java.util.Map;
/**
* @author: shudj
* @time: 2019/4/8 14:17
* @description:
*/
public class MysqlAuthServiceLoginModule extends AbstractLoginModule {
private static final Logger log = LoggerFactory.getLogger(MysqlAuthServiceLoginModule.class);
public static final String AUTH_SERVICE_OPTION = "authService";
private AuthenticationService authService;
private UsernamePrincipal usernamePrincipal;
private ServiceAdminPrincipal serviceAdminPrincipal;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
super.initialize(subject, callbackHandler, sharedState, options);
if (options.containsKey(AUTH_SERVICE_OPTION)) {
this.authService = (AuthenticationService) options.get(AUTH_SERVICE_OPTION);
} else {
log.error("This login module requires an \"authService\" option");
throw new IllegalArgumentException("This login module requires an \"authService\" option");
}
}
@Override
public boolean doLogin() throws Exception {
NameCallback nameCb = new NameCallback("username");
PasswordCallback passwordCb = new PasswordCallback("password", false);
handle(nameCb, passwordCb);
Map<String, Object> hm = this.authService.authenticate(nameCb.getName(), passwordCb.getPassword());
boolean flag = (boolean) hm.get("flag");
if (flag) {
log.debug("Login success for: {}", nameCb.getName());
String authUser = String.valueOf(hm.get("admin"));
this.usernamePrincipal = new UsernamePrincipal(nameCb.getName());
this.serviceAdminPrincipal = new ServiceAdminPrincipal(authUser);
} else {
log.debug("Login failure for: {}", nameCb.getName());
}
passwordCb.clearPassword();
return true;
}
@Override
public boolean doCommit() throws Exception {
getSubject().getPrincipals().add(this.usernamePrincipal);
// For now assume everyone who authenticates in this simple implementation are administrators.
getSubject().getPrincipals().add(this.serviceAdminPrincipal);
return true;
}
@Override
public boolean doAbort() throws Exception {
return logout();
}
@Override
public boolean doLogout() throws Exception {
getSubject().getPrincipals().remove(this.usernamePrincipal);
getSubject().getPrincipals().remove(this.serviceAdminPrincipal);
return true;
}
}
用于操作核对登录用户名和密码
import java.util.Map;
public interface AuthenticationService {
Map authenticate(String username, char[] password);
}
authenticate方法中的实现,根据自己具体要求实现
import com.thinkbiganalytics.metadata.jpa.mysql.MysqlAuthDao;
import com.thinkbiganalytics.metadata.jpa.mysql.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.Optional;
/**
* @author: shudj
* @time: 2019/4/8 14:18
* @description:
*/
@Service("authenticationService")
public class MysqlAuthenticationService implements AuthenticationService {
@Autowired
private MysqlAuthDao mysqlAuthDao;
@Override
public Map authenticate(String username, char[] password) {
Map<String, Object> hm = new Hashtable<>(2);
Optional<User> user = mysqlAuthDao.findByUsername(username);
if (user.isPresent()) {
String pw = String.valueOf(user.get().getPassword());
String newPassword = Arrays.toString(password).replace("[","")
.replace(",", "")
.replace("]", "")
.replace(" ", "");
if (pw.equals(newPassword)) {
hm.put("flag", true);
// 用户组的name
hm.put("admin", user.get().getGroup().getGroupName());
return hm;
}
}
hm.put("flag", false);
return hm;
}
}
最后需要在作为启动的ui-app和server-app里面pom.xml加入auth-mysql的依赖
更改security-api里面ServiceAdminPrincipal类的构造参数加上一个传参的构造参数
将上述的模块项目打包替换掉kylo项目下的包(4个jar包:kylo-ui-app-0.10.0.jar、kylo-service-app-0.10.0.jar、kylo-security-auth-mysql-0.10.0.jar、kylo-security-api-0.10.0.jar)
自此,再kylo-ui、kylo-server中,权限那块配置上auth-mysql,就可以实现,使用mysql中用户名和群组登录