Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加ldap认证 #139

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
Comment on lines +126 to +130
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议使用已有的jackson进行json序列化,尽量减少引入包

</dependencies>

<distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.usthe.sureness.processor.support;

import com.usthe.sureness.processor.BaseProcessor;
import com.usthe.sureness.processor.exception.SurenessAuthenticationException;
import com.usthe.sureness.subject.Subject;

/**
* @author Ed
* @create 2021-08-15 11:31
*/
public class LdapProcessor extends BaseProcessor {
@Override
public boolean canSupportSubjectClass(Class<?> var) {
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return false;
return var == LdapSubject.class;

}

@Override
public Class<?> getSupportSubjectClass() {
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return null;
return LdapSubject.class;

}

@Override
public Subject authenticated(Subject var) throws SurenessAuthenticationException {
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里需要对LadpSubject进行认证,认证成功提取对应角色筛入subject

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.usthe.sureness.subject.creater;

import com.usthe.sureness.subject.Subject;
import com.usthe.sureness.subject.SubjectCreate;
import com.usthe.sureness.subject.support.LdapSubject;
import com.usthe.sureness.util.SurenessConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
* @author Ed
* @create 2021-08-14 11:26
*/
public class LdapSubjectServletCreator implements SubjectCreate {
private static final Logger logger = LoggerFactory.getLogger(BasicSubjectServletCreator.class);

private static final int COUNT_2 = 2;


@Override
public boolean canSupportSubject(Object context) {
// ("Authorization", "Basic YWRtaW46YWRtaW4=") --- basic auth
if (context instanceof HttpServletRequest) {
String authorization = ((HttpServletRequest)context).getHeader(SurenessConstant.AUTHORIZATION);
return authorization != null && authorization.startsWith(SurenessConstant.LDAP);
} else {
return false;
}
}

@Override
public Subject createSubject(Object context) {
String authorization = ((HttpServletRequest)context).getHeader(SurenessConstant.AUTHORIZATION);
//basic auth + LDAP
String basicAuth = authorization.replace(SurenessConstant.LDAP, "").trim();
try {
basicAuth = new String(Base64.getDecoder().decode(basicAuth), StandardCharsets.UTF_8);
} catch (Exception e) {
if (logger.isInfoEnabled()) {
logger.info("can not create basic auth PasswordSubject, due {}", e.getMessage());
}
return null;
}
String[] auth = basicAuth.split(":");
if (auth.length != COUNT_2) {
if (logger.isInfoEnabled()) {
logger.info("can not create basic auth PasswordSubject by this request message");
}
return null;
}
String username = auth[0];
if (username == null || "".equals(username)) {
if (logger.isInfoEnabled()) {
logger.info("can not create basic auth PasswordSubject by this request message, appId can not null");
}
return null;
}
username = username.trim();
String password = auth[1] == null ? null : auth[1].trim();
String remoteHost = ((HttpServletRequest) context).getRemoteHost();
String requestUri = ((HttpServletRequest) context).getRequestURI();
String requestType = ((HttpServletRequest) context).getMethod();
String targetUri = requestUri.concat("===").concat(requestType).toLowerCase();
return LdapSubject.builder(username, password)
.setRemoteHost(remoteHost)
.setTargetResource(targetUri)
.build();
}
}
183 changes: 183 additions & 0 deletions core/src/main/java/com/usthe/sureness/subject/support/LdapSubject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package com.usthe.sureness.subject.support;

import com.usthe.sureness.subject.PrincipalMap;
import com.usthe.sureness.subject.Subject;

import java.util.List;

/**
* @author Ed
* @create 2021-08-12 10:04
*/
public class LdapSubject implements Subject {
private static final long serialVersionUID = 1L;

/** username **/
private String appId;

/** password **/
private String password;

/** remote IP **/
private String remoteHost;

/** the roles which this user owned **/
private List<String> ownRoles;

/** the uri resource which this user want access **/
private String targetUri;

/** the Roles which can access this resource above-targetUri **/
private List<String> supportRoles;

/** the map for principal, add your custom principal **/
private PrincipalMap principalMap;

private LdapSubject(Builder builder) {
this.appId = builder.appId;
this.password = builder.password;
this.remoteHost = builder.remoteHost;
this.ownRoles = builder.ownRoles;
this.targetUri = builder.targetUri;
this.supportRoles = builder.supportRoles;
this.principalMap = builder.principalMap;
}



@Override
public Object getPrincipal() {
return this.appId;
}

@Override
public void setPrincipal(Object var1) {
this.appId = (String) var1;
}

@Override
public PrincipalMap getPrincipalMap() {
return this.principalMap;
}

@Override
public void setPrincipalMap(PrincipalMap var1) {
this.principalMap = var1;
}

@Override
public Object getCredential() {
return this.password;
}

@Override
public void setCredential(Object var1) {
this.password = (String) var1;
}

@Override
public Object getOwnRoles() {
return this.ownRoles;
}

@Override
public void setOwnRoles(Object var1) {
this.ownRoles = (List<String>) var1;
}

@Override
public Object getTargetResource() {
return this.targetUri;
}

@Override
public void setTargetResource(Object var1) {
this.targetUri = (String) var1;
}

@Override
public Object getSupportRoles() {
return supportRoles;
}

@Override
public void setSupportRoles(Object var1) {
this.supportRoles = (List<String>) var1;
}

public static Builder builder(String appId, String password) {
return new Builder(appId, password);
}

public static Builder builder(Subject subject) {
return new Builder(subject);
}

public static class Builder {

private String appId;
private String password;
private String remoteHost;
private List<String> ownRoles;
private String targetUri;
private List<String> supportRoles;
private PrincipalMap principalMap;

public Builder(String appId, String password) {
this.appId = appId;
this.password = password;
}

@SuppressWarnings("unchecked")
public Builder(Subject subject) {
this.appId = String.valueOf(subject.getPrincipal());
this.password = String.valueOf(subject.getCredential());
this.ownRoles = (List<String>) subject.getOwnRoles();
this.targetUri = String.valueOf(subject.getTargetResource());
this.supportRoles = (List<String>) subject.getSupportRoles();
this.principalMap = subject.getPrincipalMap();
}

public Builder setPrincipal(String appId) {
this.appId = appId;
return this;
}

public Builder setPrincipalMap(PrincipalMap principalMap) {
this.principalMap = principalMap;
return this;
}

public Builder setCredentials(String password) {
this.password = password;
return this;
}

public Builder setTargetResource(String targetUri) {
this.targetUri = targetUri;
return this;
}

public Builder setOwnRoles(List<String> ownRoles) {
this.ownRoles = ownRoles;
return this;
}

public Builder setSupportRoles(List<String> supportRoles) {
this.supportRoles = supportRoles;
return this;
}

public Builder setRemoteHost(String remoteHost) {
this.remoteHost = remoteHost;
return this;
}

public LdapSubject build() {
return new LdapSubject(this);
}

}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.usthe.sureness.subject.support.ldap;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
* @author Ed
* @create 2021-08-15 0:04
* @Description: LDAP认证获取用户信息
*/
public class LDAPGetUser {
private String BASEDN;

private String PASSWORD;

private String URL;

private String STAFFSEARCHNAME;

private String GSTUDENTSEARCHNAME;

private String STUDENTSEARCHNAME;

private String PRINCIPLE;

private LDAPUtil ldapUtil;

public Map<String, Object> getUser(String uid, String pwd) {

Map<String, Object> map = new HashMap<String, Object>();
try {
//连接LDAP
LdapContext ctx = connetLDAP();
//过滤条件
String filter = "(&(objectClass=*)(uid=" + uid + "))";
//要获取的字段信息
String[] attrPersonArray = { "uid", "userPassword", "displayName", "cn", "sn", "mail", "description" };
SearchControls searchControls = new SearchControls();//搜索控件
searchControls.setSearchScope(2);//搜索范围
searchControls.setReturningAttributes(attrPersonArray);
//1.要搜索的上下文或对象的名称;2.过滤条件,可为null,默认搜索所有信息;3.搜索控件,可为null,使用默认的搜索控件
NamingEnumeration<SearchResult> answer = ctx.search("ou=People,dc=uestc,dc=edu,dc=cn", filter.toString(),searchControls);

while (answer.hasMore()) {
SearchResult result = (SearchResult) answer.next();
NamingEnumeration attrs = result.getAttributes().getAll();
while (attrs.hasMore()) {
Attribute attr = (Attribute) attrs.next();
System.out.println(attr.getID() + "=" + attr.get());
map.put(attr.getID(), attr.get());
}
}
// 在校研究生
boolean flag = ldapUtil.connectLDAP(uid, pwd, GSTUDENTSEARCHNAME);
if (!flag) {
// 在校本科生
flag = ldapUtil.connectLDAP(uid, pwd, STUDENTSEARCHNAME);
if (!flag) {
// 在校教职工
flag = ldapUtil.connectLDAP(uid, pwd, STAFFSEARCHNAME);
}
}
map.put("flag", Boolean.valueOf(flag));

} catch (Exception e) {
System.out.println("===认证失败===");
}

return map;
}

public LdapContext connetLDAP() throws NamingException {

System.out.println("====管理员开始连接====");

Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_PRINCIPAL, PRINCIPLE);//用户名
env.put(Context.SECURITY_CREDENTIALS, PASSWORD);//密码
env.put(Context.PROVIDER_URL, URL);//LDAP的地址:端口
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");//LDAP工厂类
env.put(Context.SECURITY_AUTHENTICATION, "simple");//认证类型
LdapContext ctxTDS = new InitialLdapContext(env, null);//连接

return ctxTDS;
}
}
Loading