CASシングルサイン[2] - カスタム(例えば、暗号化ポリシーなど)認証認証ポリシー、認証データソース(例えば、JDBC、JSON、第三者が繧インタフェースを要求する) - [未完]

githubの:

ここに画像を挿入説明

カスタムチェックポリシー

#継承AbstractUsernamePasswordAuthenticationHandler

公式認定戦略は、我々は、認証検証戦略をカスタマイズできるようにする必要がある、多くの場合、十分ではありません

主に政策によるカスタム構成は、CASの現実、デザインを変更し、CASでAuthenticationHandlerによって目的を達成するために、データソースを傍受するカスタム認証戦略を登録します。

それは、次の3つのステップに分かれています。

  1. デザイン独自の認証データ処理プログラム
  2. 登録CAS認証エンジンに認証インターセプター
  3. 変更の認定コンフィギュレーションCASへ

まず、依存ライブラリを追加する必要があります。

        <!-- Custom Authentication -->
        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-core-authentication-api</artifactId>
            <version>${cas.version}</version>
        </dependency>

        <!-- Custom Configuration -->
        <dependency>
            <groupId>org.apereo.cas</groupId>
            <artifactId>cas-server-core-configuration-api</artifactId>
            <version>${cas.version}</version>
        </dependency>

我々は唯一の認証モードは達成するために、伝統的なユーザ名とパスワードである場合はAbstractUsernamePasswordAuthenticationHandler、インスタンスのために、この抽象クラス缶を公式。- 設定-カスタム認証
ここに画像を挿入説明

次のようにその後、我々は、我々自身の実装クラスCustomAuthenticationHandlerをカスタマイズ

package cn.cas;

import cn.cas.utils.UserUtils;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.MessageDescriptor;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.util.StringUtils;

import javax.security.auth.login.AccountException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author lawsssscat
 */
public class CustomerAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {

    public CustomerAuthenticationHandler(
            String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
        super(name, servicesManager, principalFactory, order);
    }

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(
            UsernamePasswordCredential credential, String originalPassword)
            throws GeneralSecurityException, PreventedException {
        String username = credential.getUsername();
        String password = credential.getPassword();

        if (StringUtils.isEmpty(username)) {
            throw new AccountException("enter your username");
        } else if (StringUtils.isEmpty(password)) {
            throw new AccountException("enter your PIN");
        }

        System.out.println("username:" + username);
        System.out.println("password:" + password);

        User user = UserUtils.findUser(username);

        System.out.println("user:" + user);

        if (user == null) {
            throw new AccountException("Sorry, username not found !");
        }

        System.out.println("database username:" + user.getUsername());
        System.out.println("database password:" + user.getPassword());

        if (!password.equals(user.getPassword())) {
            throw new FailedLoginException("Sorry, password not correct !");
        }

        // 可自定义返回给客户端多个属性信息
        HashMap<String, Object> info = new HashMap<>();
        info.put("expired", user.getExpired());

        // 不能为null,否则提交信息无法认证成功!
        List<MessageDescriptor> warning = new ArrayList<>();

        return createHandlerResult(credential, this.principalFactory.createPrincipal(username, info), warning);
    }
}

どのデータベースにエンティティクラスのユーザー、ツールUserUtilsない接続点に関連して、GitHubの上でそれを見
https://github.com/LawssssCat/v-cas

2つの異なる場所でここに与えられた公式の例でバージョン理由(正式版です)、以来

  • まず、のリターンAuthenticationHandlerExecutionResultではなく、HandlerResult実際には、ソースが同じであるが、新バージョンでは、それを改名しました。
  • 第二の点は、createHandlerResult入ってくるwaringsはnullに、または他の成功した認証情報を提出することを失敗した後に、プログラムを実行することはできません!

主にコードブロックの着信を通じてCredential、ユーザー名とパスワードを取得し、クライアントに情報をカスタマイズするユーザーを返します。
ここでは、コードによって、複数の異なる方法のクライアントのカスタム属性情報に戻すことができます。

その後、我々は、構成情報、継承を注入しましたAuthenticationEventExecutionPlanConfigurer

package cn.cas;

import org.apereo.cas.authentication.AuthenticationEventExecutionPlan;
import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer;
import org.apereo.cas.authentication.AuthenticationHandler;
import org.apereo.cas.authentication.principal.DefaultPrincipalFactory;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.services.ServicesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lawsssscat
 */
@Configuration("CustomAuthenticationConfiguration")  //  此需要添加,否则bean会被注册两次(虽然不影响正常运行)
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class CustomAuthenticationConfiguration implements AuthenticationEventExecutionPlanConfigurer {

    @Autowired
    @Qualifier("servicesManager")
    private ServicesManager servicesManager;

    // 验证器交给Spring管理
    @Bean
    public AuthenticationHandler customerAuthenticationHandler() {
        System.out.println("initializating AuthenticationHandler@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        String name = CustomerAuthenticationHandler.class.getName();
        ServicesManager servicesManager = this.servicesManager;
        PrincipalFactory principalFactory = new DefaultPrincipalFactory();
        // 定义为优先优先使用
        Integer order = 1;
        return new CustomerAuthenticationHandler(name,servicesManager, principalFactory, order) ;
    }

    // 注册自定义验证器
    @Override
    public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) {
        plan.registerAuthenticationHandler(customerAuthenticationHandler());
    }
}

最後に、我々は/メイン下/ resourcesディレクトリMETA-INFディレクトリSRCで私たちの新しいを持っており、以下では、新しいファイルspring.factories、私たち自身の新しい情報に指定したコンフィギュレーションを作成します。

ここに画像を挿入説明

org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.cas.CustomAuthenticationConfiguration
-- auto-generated definition
create table sp_manager
(
    mg_id       int auto_increment comment '主键id'
        primary key,
    mg_name     varchar(32)           not null comment '名称',
    mg_pwd      char(32)              not null comment '密码',
    mg_salt     char(36)              not null comment 'salt',
    mg_time     int unsigned          not null comment '注册时间',
    role_id     tinyint(11) default 0 not null comment '角色id',
    mg_mobile   varchar(32)           null,
    mg_email    varchar(64)           null,
    mg_expired  tinyint(2)  default 0 null comment '0:表示启用 1:表示过期',
    mg_disabled tinyint(2)  default 0 null comment '0:表示启用 1:表示禁用'
)
    comment '管理员表';


ここに画像を挿入説明

、アプリケーションを起動し、ユーザー名(linken)とパスワード(123456)を入力し、我々は印刷するコンソール・メッセージを参照してください情報を照合、我々はデータをデータベースからランディングページとクエリを送信されたデータから見つけることができ、ログイン認証が成功します!

ここに画像を挿入説明

#继承AbstractPreAndPostProcessingAuthenticationHandler

実際には上記の連続はちょうど私がユーザー名とパスワードを送信した情報は、その後、どのように認証をカスタマイズすることはない、という問題がありましたか?

ここでは、継承しますAbstractPreAndPostProcessingAuthenticationHandler。このインターフェイスを
(AbstractUsernamePasswordAuthenticationHandlerは、このクラスが実装されている継承の上に実際には、それがユーザー名とパスワードの単純なチェックです。)
ここに画像を挿入説明
私たちは、カスタム実装する必要がありますのでAbstractPreAndPostProcessingAuthenticationHandlerアクセスして。

例えば、ここで私は新しいですCustomerAuthenticationHandler2、次のように、クラス:

package cn.cas.authentication.handler;

import cn.cas.model.User;
import cn.cas.utils.UserUtils;
import lombok.NonNull;
import lombok.extern.log4j.Log4j2;
import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.principal.Principal;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.springframework.util.StringUtils;

import javax.security.auth.login.AccountException;
import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;

/**
 * @author lawsssscat
 */
@Log4j2
public class CustomerAuthenticationHandler2 extends AbstractPreAndPostProcessingAuthenticationHandler {

    public CustomerAuthenticationHandler2(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
        super(name, servicesManager, principalFactory, order);
    }

    @Override
    public boolean supports(Credential credential) {
        // 判断传递过来的Credential是否是自己能处理的类型
        return credential instanceof UsernamePasswordCredential;
    }

    @Override
    protected AuthenticationHandlerExecutionResult doAuthentication(
            Credential credential)
            throws GeneralSecurityException, PreventedException {
        UsernamePasswordCredential usernamePasswordCredential = (UsernamePasswordCredential) credential;

        String username = usernamePasswordCredential.getUsername();
        String password = usernamePasswordCredential.getPassword();

        if (StringUtils.isEmpty(username)) {
            throw new AccountException("enter your username");
        } else if (StringUtils.isEmpty(password)) {
            throw new AccountException("enter your PIN");
        }

        log.info("log4j2 is running @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        System.out.println("username:" + username);
        System.out.println("password:" + password);

        User user = UserUtils.findUser(username);

        System.out.println("user:" + user);

        if (user == null) {
            throw new AccountException("Sorry, username not found !");
        }

        if (!password.equals(user.getPassword())) {
            throw new FailedLoginException("Sorry, password not correct!");
        }

        @NonNull Principal principal = this.principalFactory.createPrincipal(username);

        return createHandlerResult(usernamePasswordCredential, principal);
    }
}

ここで私は、単により多くの情報が送信され、ユーザー名とパスワードを取得するための情報、彼らは情報が送信取得することができ、変換資格を実現します。私はそれは問題ではない理解していない後に、ここで説明します。

その後、我々はCustomAuthenticationConfiguration意志CustomerAuthenticationHandlerにCustomerAuthenticationHandler2に変更しました。

    // 验证器交给Spring管理
    @Bean
    public AuthenticationHandler customerAuthenticationHandler() {
        System.out.println("initializating AuthenticationHandler@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        String name = CustomerAuthenticationHandler2.class.getName();
        ServicesManager servicesManager = this.servicesManager;
        PrincipalFactory principalFactory = new DefaultPrincipalFactory();
        // 定义为优先优先使用
        Integer order = 1;
        return new CustomerAuthenticationHandler2(name,servicesManager, principalFactory, order) ;
    }

アプリケーションを起動し、あなたは同じ効果が以前に達成することができます見つけることができます。

githubの:

公開された501元の記事 ウォンの賞賛112 ・は 20000 +を見て

おすすめ

転載: blog.csdn.net/LawssssCat/article/details/104953596