Browse Source

应用单点登录时,用户访问权限控制

Crystal.Sea 4 years ago
parent
commit
1c8ede8cc1

+ 5 - 2
ReleaseNotes.txt

@@ -1,6 +1,6 @@
-MaxKey v 2.3.0 GA	2020/**/**
+MaxKey v 2.3.0 GA	2020/11/**
  	*(MAXKEY-200901)  基于spring session的集群会话共享功能 
-    *(MAXKEY-200902) 单点注销功能
+    *(MAXKEY-200902) 单点注销功能,应用可以配置为NONE/BACK_CHANNEL/FRONT_CHANNEL三种方式,支持CAS/SAML/Default
 	*(MAXKEY-200903)  用户在线实时更新功能
 	*(MAXKEY-200904)  批量Excel用户导入功能
 	*(MAXKEY-200905)  用户注册功能
@@ -13,6 +13,9 @@
 	*(MAXKEY-200913)  权限控制 RoleAdministrators 
 	*(MAXKEY-200914)  社交账号登录优化
 	*(MAXKEY-200915)  列表界面中未”选择“情况下,弹出界面错误
+	*(MAXKEY-200916) jib(docker) 支持 ,感谢https://github.com/alanland
+	*(MAXKEY-200916)  登录过程的优化
+	*(MAXKEY-200917)  认证的优化,支持@Principal的注入
 	*(MAXKEY-200920)  依赖jar引用、更新和升级
 	    druid 1.2.1
 	    JustAuth 1.15.8

+ 3 - 5
maxkey-core/src/main/java/org/maxkey/authn/RealmAuthenticationProvider.java

@@ -29,7 +29,6 @@ import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.web.authentication.WebAuthenticationDetails;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -162,10 +161,6 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
         //set OnlineTicket
         signinPrincipal.setOnlineTicket(onlineTicket);
         ArrayList<GrantedAuthority> grantedAuthoritys = authenticationRealm.grantAuthority(userInfo);
-        //set default roles
-        grantedAuthoritys.add(new SimpleGrantedAuthority("ROLE_USER"));
-        grantedAuthoritys.add(new SimpleGrantedAuthority("ROLE_ORDINARY_USER"));
-        
         signinPrincipal.setAuthenticated(true);
         
         for(GrantedAuthority administratorsAuthority : grantedAdministratorsAuthoritys) {
@@ -174,6 +169,9 @@ public class RealmAuthenticationProvider extends AbstractAuthenticationProvider
                 _logger.trace("ROLE ADMINISTRATORS Authentication .");
             }
         }
+        _logger.debug("Granted Authority " + grantedAuthoritys);
+        
+        signinPrincipal.setGrantedAuthorityApps(authenticationRealm.queryAuthorizedApps(grantedAuthoritys));
         
         UsernamePasswordAuthenticationToken authenticationToken =
                 new UsernamePasswordAuthenticationToken(

+ 9 - 0
maxkey-core/src/main/java/org/maxkey/authn/SigninPrincipal.java

@@ -34,6 +34,7 @@ public class SigninPrincipal implements  UserDetails {
     
     OnlineTicket onlineTicket;
     ArrayList<GrantedAuthority> grantedAuthority;
+    ArrayList<GrantedAuthority> grantedAuthorityApps;
     boolean authenticated;
     boolean roleAdministrators;
 
@@ -133,6 +134,14 @@ public class SigninPrincipal implements  UserDetails {
         return false;
     }
 
+    public ArrayList<GrantedAuthority> getGrantedAuthorityApps() {
+        return grantedAuthorityApps;
+    }
+
+    public void setGrantedAuthorityApps(ArrayList<GrantedAuthority> grantedAuthorityApps) {
+        this.grantedAuthorityApps = grantedAuthorityApps;
+    }
+
     @Override
     public String getUsername() {
         if(this.userInfo != null) {

+ 10 - 0
maxkey-core/src/main/java/org/maxkey/authn/realm/AbstractAuthenticationRealm.java

@@ -110,6 +110,16 @@ public abstract class AbstractAuthenticationRealm {
     public ArrayList<GrantedAuthority> grantAuthority(UserInfo userInfo) {
         return loginService.grantAuthority(userInfo);
     }
+    
+    /**
+     * grant Authority by grantedAuthoritys
+     * 
+     * @param grantedAuthoritys
+     * @return ArrayList<GrantedAuthority Apps>
+     */
+    public ArrayList<GrantedAuthority> queryAuthorizedApps(ArrayList<GrantedAuthority> grantedAuthoritys) {
+        return loginService.queryAuthorizedApps(grantedAuthoritys);
+    }
 
     /**
      * login log write to log db

+ 23 - 1
maxkey-core/src/main/java/org/maxkey/persistence/db/LoginService.java

@@ -56,6 +56,8 @@ public class LoginService {
 
     private static final String DEFAULT_USERINFO_SELECT_STATEMENT = "SELECT * FROM  MXK_USERINFO WHERE USERNAME = ?";
     
+    private static final String DEFAULT_MYAPPS_SELECT_STATEMENT = "SELECT DISTINCT APP.ID,APP.NAME FROM MXK_APPS APP,MXK_GROUP_PRIVILEGES GP,MXK_GROUPS G  WHERE APP.ID=GP.APPID AND GP.GROUPID=G.ID AND G.ID IN(%s)";
+    
     protected JdbcTemplate jdbcTemplate;
     
     public LoginService(){
@@ -151,6 +153,24 @@ public class LoginService {
         }
     }
     
+    public ArrayList<GrantedAuthority> queryAuthorizedApps(ArrayList<GrantedAuthority> grantedAuthoritys) {
+        String grantedAuthorityString="'ROLE_ALL_USER'";
+        for(GrantedAuthority grantedAuthority : grantedAuthoritys) {
+            grantedAuthorityString += ",'"+ grantedAuthority.getAuthority()+"'";
+        }
+        
+        ArrayList<GrantedAuthority> listAuthorizedApps = (ArrayList<GrantedAuthority>) jdbcTemplate.query(
+                String.format(DEFAULT_MYAPPS_SELECT_STATEMENT, grantedAuthorityString), 
+                new RowMapper<GrantedAuthority>() {
+            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
+                return new SimpleGrantedAuthority(rs.getString("ID"));
+            }
+        });
+
+        _logger.debug("list Authorized Apps  " + listAuthorizedApps);
+        return listAuthorizedApps;
+    }
+    
     public List<Groups> queryGroups(UserInfo userInfo) {
         List<Groups> listGroups = jdbcTemplate.query(GROUPS_SELECT_STATEMENT, new RowMapper<Groups>() {
             public Groups mapRow(ResultSet rs, int rowNum) throws SQLException {
@@ -174,9 +194,11 @@ public class LoginService {
         // query roles for user
         List<Groups> listGroups = queryGroups(userInfo);
 
-        // set role for spring security
+        //set default roles
         ArrayList<GrantedAuthority> grantedAuthority = new ArrayList<GrantedAuthority>();
         grantedAuthority.add(new SimpleGrantedAuthority("ROLE_USER"));
+        grantedAuthority.add(new SimpleGrantedAuthority("ROLE_ORDINARY_USER"));
+        grantedAuthority.add(new SimpleGrantedAuthority("ROLE_ALL_USER"));
         for (Groups group : listGroups) {
             grantedAuthority.add(new SimpleGrantedAuthority(group.getId()));
         }

+ 6 - 11
maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/AppsMapper.xml

@@ -158,29 +158,24 @@
         SELECT DISTINCT
             APP.*
         FROM
-            MXK_APPS APP,MXK_GROUP_PRIVILEGES GP
+            MXK_APPS APP,MXK_GROUP_PRIVILEGES GP,MXK_GROUPS G
         WHERE
             APP.ID=GP.APPID
-            AND GP.GROUPID IN(
-                SELECT 
-                    G.ID
-                FROM  
-                    `MXK_GROUPS` G
-                WHERE 
-                    G.ID='ALL_USER_GROUP'
-                    OR G.ID IN(
+            AND GP.GROUPID=G.ID
+            AND (
+            	 G.ID='ROLE_ALL_USER'
+                 OR G.ID IN(
                       SELECT 
                         GM.GROUPID 
                       FROM 
                         MXK_GROUP_MEMBER GM,MXK_USERINFO U 
-                      WHERE 1   =   1
+                      WHERE GM.MEMBERID    =   U.ID 
                         <if test="userId != null and userId != ''">
                             AND U.ID        =   #{userId}
                         </if>
                         <if test="username != null and username != ''">
                             AND  U.USERNAME =   #{username}
                         </if>
-                        AND  GM.MEMBERID    =   U.ID 
                     )
             )
         <if test="name != null and name != ''">

+ 6 - 0
maxkey-protocols/maxkey-protocol-authorize/src/main/java/org/maxkey/authz/singlelogout/SamlSingleLogout.java

@@ -7,6 +7,12 @@ import org.maxkey.domain.apps.Apps;
 import org.maxkey.util.DateUtils;
 import org.springframework.security.core.Authentication;
 
+/**
+ * SamlSingleLogout
+ * https://apereo.github.io/cas/6.2.x/installation/Logout-Single-Signout.html
+ * @author Crystal.Sea
+ *
+ */
 public class SamlSingleLogout extends SingleLogout{
 
     /**

+ 1 - 1
maxkey-web-manage/src/main/java/org/maxkey/web/contorller/GroupMemberController.java

@@ -87,7 +87,7 @@ public class GroupMemberController {
 	@ResponseBody
 	public JpaPageResults<GroupMember> queryMemberInGroup(@ModelAttribute("groupMember")  GroupMember groupMember) {
 		_logger.debug("groupMember : "+groupMember);
-		if(groupMember.getGroupId()==null||groupMember.getGroupId().equals("")||groupMember.getGroupId().equals("ALL_USER_GROUP")){
+		if(groupMember.getGroupId()==null||groupMember.getGroupId().equals("")||groupMember.getGroupId().equals("ROLE_ALL_USER")){
 			return groupMemberService.queryPageResults("allMemberInGroup",groupMember);
 		}else{
 			return groupMemberService.queryPageResults("memberInGroup",groupMember);

+ 26 - 0
maxkey-web-maxkey/src/main/java/org/maxkey/web/interceptor/HistoryLoginAppAdapter.java

@@ -19,6 +19,8 @@ package org.maxkey.web.interceptor;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import org.maxkey.authn.SigninPrincipal;
 import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint;
 import org.maxkey.domain.HistoryLoginApps;
 import org.maxkey.domain.UserInfo;
@@ -31,6 +33,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@@ -47,6 +51,28 @@ public class HistoryLoginAppAdapter extends HandlerInterceptorAdapter {
     protected AppsService appsService;
     
     /**
+             *          判断应用访问权限
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, 
+            HttpServletResponse response, Object handler)
+            throws Exception {
+        _logger.debug("preHandle");
+        final Apps app = (Apps)WebContext.getAttribute(AuthorizeBaseEndpoint.class.getName());
+        Authentication authentication = WebContext.getAuthentication();
+        if(authentication.getPrincipal() instanceof SigninPrincipal) {
+            SigninPrincipal signinPrincipal = (SigninPrincipal)authentication.getPrincipal() ;
+            if(signinPrincipal.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(
      *          javax.servlet.http.HttpServletRequest,