zoukankan      html  css  js  c++  java
  • CAS源码学习

    创建TGT解析

    String createTicketGrantingTicket(Credentials credentials) throws TicketException;
    经过RemoteCentralAuthenticationService代理校验参数后,直接调用CentralAuthenticationServiceImpl的实现逻辑。实现逻辑代码很清爽。

      // inspektr-audit包提供的功能,能够进行操作审计
        @Audit(
            action="TICKET_GRANTING_TICKET",
            actionResolverName="CREATE_TICKET_GRANTING_TICKET_RESOLVER",
            resourceResolverName="CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER")
        @Profiled(tag = "CREATE_TICKET_GRANTING_TICKET", logFailuresSeparately = false)//自动方法耗时统计
        @Transactional(readOnly = false)//事物处理策略    
        public String createTicketGrantingTicket(final Credentials credentials) throws TicketCreationException {
            Assert.notNull(credentials, "credentials cannot be null");
            try {
                final Authentication authentication = this.authenticationManager
                    .authenticate(credentials); //调用认证管理器认证证书
                
                //认证成功即无异常抛出,则进行TGT票据生成。
                final TicketGrantingTicket ticketGrantingTicket = new TicketGrantingTicketImpl(
                    this.ticketGrantingTicketUniqueTicketIdGenerator
                        .getNewTicketId(TicketGrantingTicket.PREFIX),
                    authentication, this.ticketGrantingTicketExpirationPolicy);
                
                //将TGT票据注册
                this.ticketRegistry.addTicket(ticketGrantingTicket);
                return ticketGrantingTicket.getId();
            } catch (final AuthenticationException e) {
                throw new TicketCreationException(e);
            }
        }
    

    第一步认证凭证

    认证凭证的代码如下:

    final Authentication authentication = this.authenticationManager
                    .authenticate(credentials);
    

    其中,Authentication是个接口,它是认证成功得到的用户信息的一个抽象。他包含了认证请求成工的主要当事人身份,他还包括认证日期和额外参数的map
    。AuthenticationManager也是个接口,它是能够认证凭证的管理类的一个抽象。cas-server通过定义纯接口的编码来保持协议的可扩展性。

    • AuthenticationManager
      • AbstractAuthenticationManager 抽象模板类
        • AuthenticationManagerImpl 最常用的实现,遍历寻找证书处理器,及身份处理器,还会使用AuthenticationAttributesPopulators来尝试填充attributes参数
        • DirectMappingAuthenticationManagerImpl 直接通过凭证类型查找证书
        • LinkedAuthenticationHandlerAndCredentialsToPrincipalResolverAuthenticationManager 串联调用认证handler

    AbstractAuthenticationManager约定了AuthenticationManager要做的主要事情模板,其主要方法为:

    @Audit(
            action="AUTHENTICATION",
            actionResolverName="AUTHENTICATION_RESOLVER",
            resourceResolverName="AUTHENTICATION_RESOURCE_RESOLVER")
        @Profiled(tag = "AUTHENTICATE", logFailuresSeparately = false)
        public final Authentication authenticate(final Credentials credentials) throws AuthenticationException {
            //认证的具体处理,通过定义对象同时接收两个参数    ,其中authenticateAndObtainPrincipal由具体子类实现
            final Pair<AuthenticationHandler, Principal> pair = authenticateAndObtainPrincipal(credentials);
            // we can only get here if the above method doesn't throw an exception. And if it doesn't, then the pair must not be null.
            final Principal p = pair.getSecond();
            log.info("{} authenticated {} with credential {}.", pair.getFirst(), p, credentials);
            log.debug("Attribute map for {}: {}", p.getId(), p.getAttributes());
            
            //易变的认证信息对象,这个对象中的信息还可以修改
            Authentication authentication = new MutableAuthentication(p);
            if (pair.getFirst()instanceof NamedAuthenticationHandler) {
                final NamedAuthenticationHandler a = (NamedAuthenticationHandler) pair.getFirst();
                authentication.getAttributes().put(AuthenticationManager.AUTHENTICATION_METHOD_ATTRIBUTE, a.getName());
            }
            for (final AuthenticationMetaDataPopulator authenticationMetaDataPopulator : this.authenticationMetaDataPopulators) {
                authentication = authenticationMetaDataPopulator
                    .populateAttributes(authentication, credentials);
            }
            
            //提供一个内置map参数不可变的身份认证对象,保证安全性
            return new ImmutableAuthentication(authentication.getPrincipal(),
                authentication.getAttributes());
        }
    

    其中final Pair<AuthenticationHandler, Principal> pair = authenticateAndObtainPrincipal(credentials);很关键.他的具体逻辑由子类实现,通过查看AuthenticationManagerImpl默认认证管理实现类的逻辑代码如下:

    @Override
    protected Pair<AuthenticationHandler, Principal> authenticateAndObtainPrincipal(final Credentials credentials) throws AuthenticationException {
        boolean foundSupported = false;
        boolean authenticated = false;
        AuthenticationHandler authenticatedClass = null;
        String handlerName;
        
        //寻找支持的处理器,并进行认证
        for (final AuthenticationHandler authenticationHandler : this.authenticationHandlers) {
            if (authenticationHandler.supports(credentials)) {
                foundSupported = true;
                handlerName = authenticationHandler.getClass().getName();
                try {
                    if (!authenticationHandler.authenticate(credentials)) {
                        log.info("{} failed to authenticate {}", handlerName, credentials);
                    } else {
                        log.info("{} successfully authenticated {}", handlerName, credentials);
                        authenticatedClass = authenticationHandler;
                        authenticated = true;
                        break;
                    }
                } catch (final Exception e) {
                    handleError(handlerName, credentials, e);
                }
            }
        }
    
        //凭证不支持的处理
        if (!authenticated) {
            if (foundSupported) {
                throw BadCredentialsAuthenticationException.ERROR;
            }
            throw UnsupportedCredentialsException.ERROR;
        }
    
        foundSupported = false;
    
        //凭证支持转化获取具体的认证身份
        for (final CredentialsToPrincipalResolver credentialsToPrincipalResolver : this.credentialsToPrincipalResolvers) {
            if (credentialsToPrincipalResolver.supports(credentials)) {
                final Principal principal = credentialsToPrincipalResolver.resolvePrincipal(credentials);
                log.info("Resolved principal " + principal);
                foundSupported = true;
                if (principal != null) {
                    return new Pair<AuthenticationHandler,Principal>(authenticatedClass, principal);
                }
            }
        }
    
        //身份转化不支持处理
        if (foundSupported) {
            if (log.isDebugEnabled()) {
                log.debug("CredentialsToPrincipalResolver found but no principal returned.");
            }
    
            throw BadCredentialsAuthenticationException.ERROR;
        }
    
        log.error("CredentialsToPrincipalResolver not found for " + credentials.getClass().getName());
        throw UnsupportedCredentialsException.ERROR;
    }
    

    上段代码中可以发现AuthenticationHandler接口主要是凭证认证的处理类,其实现类结构如下:

    • AuthenticationHandler
      • HttpBasedServiceCredentialsAuthenticationHandler
      • NamedAuthenticationHandler
        • AbstractPreAndPostProcessingAuthenticationHandler
  • 相关阅读:
    Windows下载Vim
    分享:分享几个程序员使用的网站
    分享:C语言大礼包(PDF)
    将vscode打造成强大的C/C++ IDE
    最适合做C/C++开发的IDE
    bzoj 2244
    bzoj 1492
    bzoj 3262
    bzoj 1176
    bzoj 2961
  • 原文地址:https://www.cnblogs.com/alcc/p/9201915.html
Copyright © 2011-2022 走看看