Explorar el Código

单点注销 RC1

Crystal.Sea hace 4 años
padre
commit
f635ed358c

+ 53 - 0
maxkey-core/src/main/java/org/maxkey/authn/online/InMemoryOnlineTicketServices.java

@@ -0,0 +1,53 @@
+/*
+ * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.maxkey.authn.online;
+
+import java.time.Duration;
+
+import org.ehcache.UserManagedCache;
+import org.ehcache.config.builders.ExpiryPolicyBuilder;
+import org.ehcache.config.builders.UserManagedCacheBuilder;
+
+
+public class InMemoryOnlineTicketServices implements OnlineTicketServices{
+
+	protected final static  UserManagedCache<String, OnlineTicket> onlineTicketStore = 
+			UserManagedCacheBuilder.newUserManagedCacheBuilder(String.class, OnlineTicket.class)
+				.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMinutes(30)))
+				.build(true);
+
+	
+	@Override
+	public void store(String ticketId, OnlineTicket ticket) {
+	    onlineTicketStore.put(ticketId, ticket);
+	}
+
+	@Override
+	public OnlineTicket remove(String ticketId) {
+	    OnlineTicket ticket=onlineTicketStore.get(ticketId);	
+	    onlineTicketStore.remove(ticketId);
+		return ticket;
+	}
+
+    @Override
+    public OnlineTicket get(String ticketId) {
+        OnlineTicket ticket=onlineTicketStore.get(ticketId); 
+        return ticket;
+    }
+
+}

+ 36 - 0
maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicket.java

@@ -0,0 +1,36 @@
+package org.maxkey.authn.online;
+
+import java.io.Serializable;
+
+import org.maxkey.domain.apps.Apps;
+
+public class OnlineTicket implements Serializable{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 9008067569150338296L;
+
+    public String id;
+    
+    private Apps authorizeApps;
+    
+
+    public OnlineTicket(String id) {
+        super();
+        this.id = id;
+    }
+    
+    
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("OnlineTicket [id=");
+        builder.append(id);
+        builder.append("]");
+        return builder.toString();
+    }
+    
+    
+}

+ 29 - 0
maxkey-core/src/main/java/org/maxkey/authn/online/OnlineTicketServices.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.maxkey.authn.online;
+
+
+public interface OnlineTicketServices {
+
+	public  void store(String ticketId, OnlineTicket ticket);
+
+    public  OnlineTicket remove(String ticket);
+    
+    public  OnlineTicket get(String ticketId);
+
+}

+ 76 - 0
maxkey-core/src/main/java/org/maxkey/authn/online/RedisOnlineTicketServices.java

@@ -0,0 +1,76 @@
+/*
+ * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+
+package org.maxkey.authn.online;
+
+import org.maxkey.persistence.redis.RedisConnection;
+import org.maxkey.persistence.redis.RedisConnectionFactory;
+
+
+public class RedisOnlineTicketServices implements OnlineTicketServices {
+
+	
+	protected int serviceTicketValiditySeconds = 60 * 30; //default 30 minutes.
+	
+	RedisConnectionFactory connectionFactory;
+	
+	public static String PREFIX="REDIS_ONLINE_TICKET_";
+	/**
+	 * @param connectionFactory
+	 */
+	public RedisOnlineTicketServices(RedisConnectionFactory connectionFactory) {
+		super();
+		this.connectionFactory = connectionFactory;
+	}
+	
+	/**
+	 * 
+	 */
+	public RedisOnlineTicketServices() {
+		
+	}
+
+	public void setConnectionFactory(RedisConnectionFactory connectionFactory) {
+		this.connectionFactory = connectionFactory;
+	}
+
+	@Override
+	public void store(String ticketId, OnlineTicket ticket) {
+		RedisConnection conn=connectionFactory.getConnection();
+		conn.setexObject(PREFIX+ticketId, serviceTicketValiditySeconds, ticket);
+		conn.close();
+	}
+
+	@Override
+	public OnlineTicket remove(String ticketId) {
+		RedisConnection conn=connectionFactory.getConnection();
+		OnlineTicket ticket = conn.getObject(PREFIX+ticketId);
+		conn.delete(PREFIX+ticketId);
+		conn.close();
+		return ticket;
+	}
+
+    @Override
+    public OnlineTicket get(String ticketId) {
+        RedisConnection conn=connectionFactory.getConnection();
+        OnlineTicket ticket = conn.getObject(PREFIX+ticketId);
+        conn.close();
+        return ticket;
+    }
+
+	
+}

+ 25 - 1
maxkey-core/src/main/java/org/maxkey/domain/apps/Apps.java

@@ -109,7 +109,10 @@ public class Apps extends JpaBaseDomain implements Serializable {
     private String principal;
     @Column
     private String credentials;
-
+    @Column
+    private String logoutUrl;
+    @Column
+    private int logoutType;
     /*
      * extendAttr
      */
@@ -516,6 +519,23 @@ public class Apps extends JpaBaseDomain implements Serializable {
     public void setInducer(String inducer) {
         this.inducer = inducer;
     }
+    
+
+    public String getLogoutUrl() {
+        return logoutUrl;
+    }
+
+    public void setLogoutUrl(String logoutUrl) {
+        this.logoutUrl = logoutUrl;
+    }
+
+    public int getLogoutType() {
+        return logoutType;
+    }
+
+    public void setLogoutType(int logoutType) {
+        this.logoutType = logoutType;
+    }
 
     @Override
     public String toString() {
@@ -552,6 +572,10 @@ public class Apps extends JpaBaseDomain implements Serializable {
         builder.append(principal);
         builder.append(", credentials=");
         builder.append(credentials);
+        builder.append(", logoutUrl=");
+        builder.append(logoutUrl);
+        builder.append(", logoutType=");
+        builder.append(logoutType);
         builder.append(", isExtendAttr=");
         builder.append(isExtendAttr);
         builder.append(", extendAttr=");

+ 16 - 0
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/CasSingleLogout.java

@@ -0,0 +1,16 @@
+package org.maxkey.authz.singlelogout;
+
+public class CasSingleLogout extends SingleLogout{
+
+    public String logoutRequestMessage=
+            "<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"%s\" Version=\"2.0\" "
+            + "IssueInstant=\"%s\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">%s"
+            + "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
+
+    @Override
+    public void sendRequest() {
+        // TODO Auto-generated method stub
+        
+    }
+    
+}

+ 16 - 0
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/DefaultSingleLogout.java

@@ -0,0 +1,16 @@
+package org.maxkey.authz.singlelogout;
+
+public class DefaultSingleLogout extends SingleLogout{
+
+    public String logoutRequestMessage=
+            "<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"%s\" Version=\"2.0\" "
+            + "IssueInstant=\"%s\"><saml:NameID xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">%s"
+            + "</saml:NameID><samlp:SessionIndex>%s</samlp:SessionIndex></samlp:LogoutRequest>";
+
+    @Override
+    public void sendRequest() {
+        // TODO Auto-generated method stub
+        
+    }
+    
+}

+ 18 - 0
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/LogoutType.java

@@ -0,0 +1,18 @@
+package org.maxkey.authz.singlelogout;
+
+public class LogoutType {
+
+    /**
+     * For no SLO.
+     */
+    public static int NONE = 0;
+    /**
+     * For back channel SLO.
+     */
+    public static  int BACK_CHANNEL = 1;
+    /**
+     * For front channel SLO.
+     */
+    public static  int FRONT_CHANNEL = 2;
+
+}

+ 7 - 0
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/SingleLogout.java

@@ -0,0 +1,7 @@
+package org.maxkey.authz.singlelogout;
+
+public abstract class SingleLogout {
+
+    
+    public abstract void sendRequest() ;
+}

+ 5 - 0
maxkey-web-manage/src/main/resources/messages/message.properties

@@ -275,6 +275,11 @@ apps.visible.all=\u6240\u6709\u7528\u6237
 apps.visible.internet=\u5185\u90e8\u7528\u6237
 apps.visible.intranet=\u5916\u90e8\u7528\u6237
 apps.loginUrl=\u767b\u5f55\u5730\u5740
+apps.logoutUrl=\u6ce8\u9500\u5730\u5740
+apps.logoutType=\u6ce8\u9500\u65b9\u5f0f
+apps.logoutType.none=\u65e0
+apps.logoutType.back_channel=\u540e\u53f0
+apps.logoutType.front_channel=\u524d\u53f0
 apps.credential=\u51ed\u8bc1\u7c7b\u578b
 apps.credential.user-defined=\u7528\u6237\u81ea\u5b9a\u4e49
 apps.credential.shared=\u5e94\u7528\u5171\u4eab

+ 5 - 0
maxkey-web-manage/src/main/resources/messages/message_en.properties

@@ -275,6 +275,11 @@ apps.visible.all=All
 apps.visible.internet=Internet
 apps.visible.intranet=Intranet
 apps.loginUrl=loginUrl
+apps.logoutUrl=logoutUrl
+apps.logoutType=logoutType
+apps.logoutType.none=NONE
+apps.logoutType.back_channel=BACK_CHANNEL
+apps.logoutType.front_channel=FRONT_CHANNEL
 apps.credential=credential
 apps.credential.user-defined=user-defined
 apps.credential.shared=shared

+ 5 - 0
maxkey-web-manage/src/main/resources/messages/message_zh_CN.properties

@@ -275,6 +275,11 @@ apps.visible.all=\u6240\u6709\u7528\u6237
 apps.visible.internet=\u5185\u90e8\u7528\u6237
 apps.visible.intranet=\u5916\u90e8\u7528\u6237
 apps.loginUrl=\u767b\u5f55\u5730\u5740
+apps.logoutUrl=\u6ce8\u9500\u5730\u5740
+apps.logoutType=\u6ce8\u9500\u65b9\u5f0f
+apps.logoutType.none=\u65e0
+apps.logoutType.back_channel=\u540e\u53f0
+apps.logoutType.front_channel=\u524d\u53f0
 apps.credential=\u51ed\u8bc1\u7c7b\u578b
 apps.credential.user-defined=\u7528\u6237\u81ea\u5b9a\u4e49
 apps.credential.shared=\u5e94\u7528\u5171\u4eab

+ 14 - 0
maxkey-web-manage/src/main/resources/templates/views/apps/appAddCommon.ftl

@@ -30,6 +30,20 @@
          </td>
       </tr>
       <tr>
+         <th><@locale code="apps.logoutUrl"/>:</th>
+         <td>
+            <input  type="text" id="logoutUrl" class="form-control"  name="logoutUrl"  title="" value=""/>
+         </td>
+         <th><@locale code="apps.logoutType"/></th>
+         <td>
+         	<select  id="logoutType" name="logoutType" class="form-control" >
+				<option value="0" selected ><@locale code="apps.logoutType.none"/></option>
+				<option value="1" ><@locale code="apps.logoutType.back_channel"/></option>
+				<option value="2" ><@locale code="apps.logoutType.front_channel"/></option>
+			</select>
+         </td>
+      </tr>
+      <tr>
          <th style="width:15%;"><@locale code="apps.protocol"/>:</th>
          <td style="width:35%;">
          	<span  id="protocol_text" >${model.protocol!}</span>

+ 14 - 0
maxkey-web-manage/src/main/resources/templates/views/apps/appUpdateCommon.ftl

@@ -30,6 +30,20 @@
          </td>
       </tr>
       <tr>
+         <th><@locale code="apps.logoutUrl"/>:</th>
+         <td>
+            <input  type="text" id="logoutUrl" class="form-control"  name="logoutUrl"  title="" value="${model.logoutUrl!}"/>
+         </td>
+         <th><@locale code="apps.logoutType"/></th>
+         <td>
+         	<select  id="logoutType" name="logoutType" class="form-control" >
+				<option value="0" <#if 0==model.logoutType!>selected</#if> ><@locale code="apps.logoutType.none"/></option>
+				<option value="1" <#if 1==model.logoutType!>selected</#if> ><@locale code="apps.logoutType.back_channel"/></option>
+				<option value="2" <#if 2==model.logoutType!>selected</#if> ><@locale code="apps.logoutType.front_channel"/></option>
+			</select>
+         </td>
+      </tr>
+      <tr>
          <th><@locale code="apps.protocol"/>:</th>
          <td>
             <input type="text" class="form-control" id="protocol" name="protocol"  title="" value="${model.protocol!}"/>