Laravel配置Windows集成認證和自動認證失敗后跳轉到頁面認證

接觸Laravel是2018年,當年期望借此能從一個做小板凳的升級為做傢具的,搞不好成為一專業木匠.可一轉眼都2020年了,我依然是在門外轉悠,偶爾做做小板凳,想想也是頗為汗顏.
這就是我等的通病,沒恒心缺毅力,所以人到中年,淪為一個數字.
然而,只要今天又想到學,那就記錄下來備用.萬一后面用到呢!

前言

Laravel 支持多種認證方式,對企業環境來說AD LDAP認證的方式就很實用,但更好的方式是使用Windows集成認證,省掉輸入賬號密碼這一步.
單純的配置Laravel使用Windows集成認證并不複雜,我的目標是加入Windows 域的電腦通過Windows集成認證,未加入域的電腦通過頁面認證.
看起來很簡單的一個任務居然斷斷續續的花了三天才算成功.

正文

1. 讓Laravel 可以通過Windows 集成認證

1.1 Linux 啟用Windows集成認證(略)

1.2 Laravel 獲取通過Windows集成認證后的身份信息

1.2.1 新建一個用于Windows集成認證的中間件WinSSO
[root@ksyoweb02 ldap]# php artisan make:middleware WinSSO
Middleware created successfully.
1.2.2 編輯WinSSO[app\Http\Middleware\WinSSO.php],使其可驗證User.
<?php

namespace App\Http\Middleware;

use Closure;
use App\User;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\Factory as Auth;

class WinSSO
{
    protected $auth;
    public function __construct(Auth $auth)
    {
        $this->auth = $auth;
    }
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->server('REMOTE_USER') ){//如果通過認證,會有REMOTE_USER
            $ssoUserArr=explode("@",$request->server('REMOTE_USER'));//REMOTE_USER中包含域名,分割一下
            if ($user = User::where('username', $ssoUserArr[0])->first())//在USER對象中查詢是否匹配
            {
                 $this->auth->login($user);//授權
            }
        }
        else
        {
            return redirect()->guest('login');//否則跳回登錄窗口
        }
        return $next($request);//授權后的信息返回
    }
}

1.2.3 在kernel.php[app\Http\Kernel.php]中註冊中間件,注意加入到$routeMiddleware中
  protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
	    'op' => \App\Http\Middleware\AuthOp::class,
    	'sso' => \App\Http\Middleware\WinSSO::class,
    ];
1.2.4 在需要的Controller中使用中間件,比如HomeController
public function __construct()
    {//不同情境下使用不同中間件來進行驗證
        if(array_key_exists('REMOTE_USER',$_SERVER)){
            $this->middleware('sso');
        }else{
            $this->middleware('auth');
        }
    }

2. 讓未加入域的電腦不彈出http base auth,直接轉到頁面認證

在這部份我花費了比較長的時間,主要是因為腦子不夠清晰走了彎路.重點如下:

  1. laravel 入口文件為index.php,可以看作每次訪問都只是訪問index.php這一個文件
  2. 401 重定向有限制,而且行為比較詭異
    我最終的方案是使用vhost+軟鏈接,讓同一工程有兩個不同入口,分別採用不同的權限以達到目的.

2.1 為工程目錄軟鏈接一個虛擬目錄

[root@ksyoweb02 html]# ln -s website website8000

2.2 用兩個vhost來分配不同的訪問權限方式

[root@ksyoweb02 html]# vim /etc/httpd/vhost.d/web.conf
#80端口需要SSO認證
<VirtualHost *:80>
    ServerName ksyoweb02.youngoptics.com
    ServerAlias ksyoweb02.youngoptics.com
    DocumentRoot /var/www/html/website/public
</VirtualHost>
<Directory "/var/www/html/website/public">
    Options +Includes -Indexes
    AllowOverride All
        AuthType Kerberos
        AuthName "HHH"
        KrbMethodNegotiate On
        KrbMethodK5Passwd Off #自動認證失敗時不彈出窗口要求賬號密碼
        KrbAuthRealms YOUNGOPTICS.COM
        Krb5KeyTab /etc/httpd/ksyoweb02.keytab
        KrbServiceName HTTP
        require valid-user
        ErrorDocument 401 /redirect.html #401 時訪問redirect.html 這個文件,這里不能直接外部url
        <Files "redirect.html">
            require all granted  #指定訪問此文件時不需要驗證
        </files>
</Directory>
[root@ksyoweb02 html]# vim /etc/httpd/vhost.d/web8000.conf
Listen 8000 #8000端口不需要SSO認證
<VirtualHost *:8000>
    ServerName ksyoweb02
    ServerAlias ksyoweb02
    DocumentRoot /var/www/html/website8000/public
</VirtualHost>
<Directory "/var/www/html/website8000/public">
    Options +Includes -Indexes
    AllowOverride All
    Require all granted
</Directory>

2.3 編輯redirect.html文件,以達到跳轉目的.

<html>
   <head>
      <title>Redirect To Login Form</title>
      <meta charset="utf-8">
      <meta http-equiv = "refresh" content = "2; url = http://ksyoweb02.youngoptics.com:8000" />
   </head>
   <body>
      <p>自動認證失敗,正在轉入登錄界面!</p>
   </body>
</html>

此處我原想用php來做跳轉,邪門的是如果用php 跳轉,那不管401不401都會跳走,但如果是php輸出內容又可以,真是日了狗了.

<?PHP
$url = "http://ksyoweb02.youngoptics.com:8000";
Header("HTTP/1.1 303 See Other");
Header("Location: $url");
exit;
?>

結束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值