Browse Source

SingleSignOn Interceptor

MaxKey 3 years ago
parent
commit
3377d957ed
14 changed files with 244 additions and 42 deletions
  1. 1 1
      maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/endpoint/ConsumerEndpoint.java
  2. 17 0
      maxkey-web-frontend/maxkey-web-app/src/app/routes/config/accouts/accouts.component.spec.ts
  3. 17 0
      maxkey-web-frontend/maxkey-web-app/src/app/routes/config/accouts/accouts.component.ts
  4. 14 6
      maxkey-web-frontend/maxkey-web-app/src/app/service/authn.service.ts
  5. 17 0
      maxkey-web-frontend/maxkey-web-app/src/app/shared/utils/knowhost.ts
  6. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/group-members/member-groups-editer/member-groups-editer.component.spec.ts
  7. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/group-members/member-groups-editer/member-groups-editer.component.ts
  8. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/role-members/member-roles-editer/member-roles-editer.component.spec.ts
  9. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/role-members/member-roles-editer/member-roles-editer.component.ts
  10. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/users/password/password.component.spec.ts
  11. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/users/password/password.component.ts
  12. 17 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/shared/utils/knowhost.ts
  13. 1 33
      maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/HistorySignOnAppInterceptor.java
  14. 58 2
      maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/SingleSignOnInterceptor.java

+ 1 - 1
maxkey-protocols/maxkey-protocol-saml-2.0/src/main/java/org/maxkey/authz/saml20/consumer/endpoint/ConsumerEndpoint.java

@@ -130,7 +130,7 @@ public class ConsumerEndpoint {
 	
 	SAML2ValidatorSuite validatorSuite = new SAML2ValidatorSuite();
 
-	@RequestMapping(value = "/consumer/saml/v20/{id}")
+	@RequestMapping(value = "/authz/saml20/consumer/{id}")
 	public ModelAndView consumer(HttpServletRequest request,
 			HttpServletResponse response, @PathVariable("id") String appId)
 			throws Exception {

+ 17 - 0
maxkey-web-frontend/maxkey-web-app/src/app/routes/config/accouts/accouts.component.spec.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { AccoutsComponent } from './accouts.component';

+ 17 - 0
maxkey-web-frontend/maxkey-web-app/src/app/routes/config/accouts/accouts.component.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { Component, ChangeDetectorRef, OnInit, Input } from '@angular/core';
 import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { Router, ActivatedRoute } from '@angular/router';

+ 14 - 6
maxkey-web-frontend/maxkey-web-app/src/app/service/authn.service.ts

@@ -44,8 +44,9 @@ export class AuthnService {
   ) { }
 
   setRedirectUri(redirect_uri: string) {
-    this.redirect_uri = CryptoJS.enc.Base64url.parse(redirect_uri).toString();
-    localStorage.setItem('redirect_uri', this.redirect_uri);
+    this.redirect_uri = CryptoJS.enc.Base64url.parse(redirect_uri).toString(CryptoJS.enc.Utf8);
+    console.log(`redirect_uri ${this.redirect_uri}`);
+    localStorage.setItem(CONSTS.REDIRECT_URI, this.redirect_uri);
   }
 
   get(authParam: any) {
@@ -91,8 +92,8 @@ export class AuthnService {
       subHostName = `${hostnames[hostnames.length - 2]}.${hostnames[hostnames.length - 1]}`;
     }
 
-    this.cookieService.set(CONSTS.CONGRESS, authJwt.token);
-    this.cookieService.set(CONSTS.ONLINE_TICKET, authJwt.ticket, { domain: subHostName });
+    this.cookieService.set(CONSTS.CONGRESS, authJwt.token, { path: '/' });
+    this.cookieService.set(CONSTS.ONLINE_TICKET, authJwt.ticket, { domain: subHostName, path: '/' });
 
     if (authJwt.remeberMe) {
       localStorage.setItem(CONSTS.REMEMBER, authJwt.remeberMe);
@@ -152,10 +153,17 @@ export class AuthnService {
       if (url.includes('/passport')) {
         url = '/';
       }
+
+      if (localStorage.getItem(CONSTS.REDIRECT_URI) != null) {
+        this.redirect_uri = `${localStorage.getItem(CONSTS.REDIRECT_URI)}`;
+        localStorage.removeItem(CONSTS.REDIRECT_URI);
+      }
+
       if (this.redirect_uri != '') {
-        url = this.redirect_uri;
-        this.redirect_uri = '';
+        console.log(`redirect_uri ${this.redirect_uri}`);
+        location.href = this.redirect_uri;
       }
+
       this.router.navigateByUrl(url);
     });
   }

+ 17 - 0
maxkey-web-frontend/maxkey-web-app/src/app/shared/utils/knowhost.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 export function knowHost() {
     let hostArray: string[] = new Array('localhost', 'sso.maxkey.top', 'mgt.maxkey.top', 'sso.maxsso.net', 'mgt.maxsso.net');
     for (var i = 0; i < hostArray.length; i++) {

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/group-members/member-groups-editer/member-groups-editer.component.spec.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { MemberGroupsEditerComponent } from './member-groups-editer.component';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/group-members/member-groups-editer/member-groups-editer.component.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, OnInit, Input } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { _HttpClient } from '@delon/theme';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/role-members/member-roles-editer/member-roles-editer.component.spec.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { MemberRolesEditerComponent } from './member-roles-editer.component';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/role-members/member-roles-editer/member-roles-editer.component.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, OnInit, Input } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { _HttpClient } from '@delon/theme';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/users/password/password.component.spec.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { PasswordComponent } from './password.component';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/users/password/password.component.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 import { Component, ChangeDetectorRef, OnInit, Input } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { NzMessageService } from 'ng-zorro-antd/message';

+ 17 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/shared/utils/knowhost.ts

@@ -1,3 +1,20 @@
+/*
+ * Copyright [2022] [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.
+ */
+ 
+
 export function knowHost() {
     let hostArray: string[] = new Array('localhost', 'sso.maxkey.top', 'mgt.maxkey.top', 'sso.maxsso.net', 'mgt.maxsso.net');
     for (var i = 0; i < hostArray.length; i++) {

+ 1 - 33
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/HistorySignOnAppInterceptor.java

@@ -32,7 +32,6 @@ import org.maxkey.web.WebContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.AsyncHandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
@@ -46,38 +45,7 @@ public class HistorySignOnAppInterceptor  implements AsyncHandlerInterceptor  {
 
     @Autowired
     protected AppsService appsService;
-    
-    /**
-             *          判断应用访问权限
-     */
-    @Override
-    public boolean preHandle(HttpServletRequest request, 
-            HttpServletResponse response, Object handler)
-            throws Exception {
-        _logger.debug("preHandle {}",request.getRequestURI());
-        Apps app = (Apps)WebContext.getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP);
-        if(app == null) {
-        	String appId ="";
-        	//JWT
-        	if(request.getRequestURI().contains("/authz/jwt/")) {
-        		String [] requestURI = request.getRequestURI().split("/");
-        		appId = requestURI[requestURI.length -1];
-        	}
-        	_logger.debug("appId {}",appId);
-        	app = appsService.get(appId,true);
-        }
-        SignPrincipal principal = AuthorizationUtils.getPrincipal();
-        if(principal != null && app !=null) {
-            if(principal.getGrantedAuthorityApps().contains(new SimpleGrantedAuthority(app.getId()))) {
-                _logger.trace("preHandle have authority access " + app);
-                return true;
-            }
-        }
-        _logger.debug("preHandle not have authority access " + app);
-        return false;
-    }
-    
-    
+
     /**
      * postHandle .
      * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(

+ 58 - 2
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/SingleSignOnInterceptor.java

@@ -19,14 +19,23 @@ package org.maxkey.web.interceptor;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.maxkey.authn.SignPrincipal;
 import org.maxkey.authn.jwt.AuthTokenService;
 import org.maxkey.authn.session.SessionManager;
 import org.maxkey.authn.web.AuthorizationUtils;
+import org.maxkey.authz.cas.endpoint.ticket.CasConstants;
+import org.maxkey.authz.oauth2.common.OAuth2Constants;
 import org.maxkey.configuration.ApplicationConfig;
 import org.maxkey.crypto.Base64Utils;
+import org.maxkey.entity.apps.Apps;
+import org.maxkey.persistence.service.AppsCasDetailsService;
+import org.maxkey.persistence.service.AppsService;
+import org.maxkey.web.WebConstants;
+import org.maxkey.web.WebContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.web.util.UrlUtils;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.AsyncHandlerInterceptor;
@@ -44,6 +53,12 @@ public class SingleSignOnInterceptor  implements AsyncHandlerInterceptor {
     @Autowired
 	AuthTokenService authTokenService ;
     
+    @Autowired
+    AppsService appsService;
+    
+    @Autowired
+    AppsCasDetailsService casDetailsService;
+    
     @Override
     public boolean preHandle(HttpServletRequest request, 
             HttpServletResponse response, Object handler)
@@ -53,13 +68,54 @@ public class SingleSignOnInterceptor  implements AsyncHandlerInterceptor {
     	AuthorizationUtils.authenticateWithCookie(
     				request,authTokenService,sessionManager);
 
-        if(AuthorizationUtils.isNotAuthenticated()){
+        if(AuthorizationUtils.isNotAuthenticated()) {
         	String loginUrl = applicationConfig.getFrontendUri() + "/#/passport/login?redirect_uri=%s";
         	String redirect_uri = UrlUtils.buildFullRequestUrl(request);
         	String base64RequestUrl = Base64Utils.base64UrlEncode(redirect_uri.getBytes());
-        	_logger.debug("No Authentication ... Redirect to /passport/login , redirect_uri {}",redirect_uri);
+        	_logger.debug("No Authentication ... Redirect to /passport/login , redirect_uri {} , base64 {}",
+        					redirect_uri ,base64RequestUrl);
         	response.sendRedirect(String.format(loginUrl,base64RequestUrl));
+        	return false;
         }
+        
+        //判断应用访问权限
+        if(AuthorizationUtils.isAuthenticated()){
+	        _logger.debug("preHandle {}",request.getRequestURI());
+	        Apps app = (Apps)WebContext.getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP);
+	        if(app == null) {
+	        	
+	        	String requestURI = request.getRequestURI();
+	        	if(requestURI.contains("/authz/cas/login")) {//for CAS service
+	        		app = casDetailsService.getAppDetails(
+	        				request.getParameter(CasConstants.PARAMETER.SERVICE), true);
+	        	}else if(requestURI.contains("/authz/jwt/")
+	        			||requestURI.contains("/authz/api/")
+	        			||requestURI.contains("/authz/formbased/")
+	        			||requestURI.contains("/authz/tokenbased/")
+	        			||requestURI.contains("/authz/api/")
+	        			||requestURI.contains("/authz/saml20/consumer/")
+	        			||requestURI.contains("/authz/saml20/idpinit/")
+	        			||requestURI.contains("/authz/cas/")
+	        	) {//for id end of URL
+	        		String [] requestURIs = requestURI.split("/");
+	        		String appId = requestURIs[requestURIs.length -1];
+	        		_logger.debug("appId {}",appId);
+		        	app = appsService.get(appId,true);
+	        	}else if(requestURI.contains("/authz/oauth/v20/authorize")) {//oauth
+		        	app = appsService.get(
+		        			request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID),true);
+	        	}
+	        }
+	        SignPrincipal principal = AuthorizationUtils.getPrincipal();
+	        if(principal != null && app !=null) {
+	            if(principal.getGrantedAuthorityApps().contains(new SimpleGrantedAuthority(app.getId()))) {
+	                _logger.trace("preHandle have authority access {}" , app);
+	                return true;
+	            }
+	        }
+	        _logger.debug("preHandle not have authority access " + app);
+	        return false;
+    	}
         return true;
     }