在 ASP.NET Web Forms 上使用 OAuth
最近遇到舊系統要串接 OAuth,發現有些方法不像在 ASP.NET Core 上,有 Middleware 可以用,所以記錄一下,用 .NET Framework 4.8
的專案為範例。
使用 OWIN 串接 OAuth
安裝
Microsoft.Owin
Nuget Packages版本為
4.2.2
1
2
3
4Install-Package Microsoft.Owin.Host.SystemWeb
Install-Package Microsoft.Owin.Security
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Security.OpenIdConnect新增
OWIN Startup class
安裝
Microsoft.Owin.Host.SystemWeb
後就會多出這個選項在
Startup.cs
新增下列程式碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33public class Startup
{
private readonly string _authority = ConfigurationManager.AppSettings["Auth_Authority"];
private readonly string _clientId = ConfigurationManager.AppSettings["Auth_ClientId"];
private readonly string _clientSecret = ConfigurationManager.AppSettings["Auth_ClientSecret"];
private readonly string _redirectUri = ConfigurationManager.AppSettings["Auth_RedirectUri"];
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
private void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = new PathString("/Login")
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = _authority,
ClientId = _clientId,
ClientSecret = _clientSecret,
RedeemCode = true,
RedirectUri = _redirectUri,
ResponseType = OpenIdConnectResponseType.Code,
SaveTokens = true
});
}
}配置
LoginPath = new PathString("/Login")
,Middleware 會以302 Found
重新導向401 Unauthorized
到登入頁面。在
Global.asax.cs
新增下列程式碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
void Application_AuthenticateRequest(object sender, EventArgs e)
{
var requestPath = Context.Request.FilePath;
var isLoginPath = requestPath.IndexOf("/Login", 0, StringComparison.OrdinalIgnoreCase) != -1;
var isCallbackPath = requestPath.IndexOf("/signin-oidc", 0, StringComparison.OrdinalIgnoreCase) != -1;
var hasUser = User != null;
var isAuthenticated = hasUser && User.Identity.IsAuthenticated;
if (!isLoginPath && !isCallbackPath && !isAuthenticated)
{
Response.StatusCode = (int)HttpStatusCode.Unauthorized;
Response.End();
}
}
}配置
Global Authorization Policy
,讓系統預設為必須經過驗證。在 ASP.NET Core 上可以使用 Require authenticated users,在 ASP.NET Web Forms 上目前沒有找到方法,所以自行實作。在
Login.aspx.cs
新增下列程式碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (!User.Identity.IsAuthenticated)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.Challenge();
return;
}
var returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl != null)
{
Response.Redirect(returnUrl);
}
else
{
Response.Redirect("/Default");
}
}
}
}使用
HttpContext.Current.GetOwinContext().Authentication.Challenge()
就會根據Startup
的配置,自動導向到Identity Provider
進行驗證。
如果要登出的話,使用HttpContext.Current.GetOwinContext().Authentication.SignOut()
。登入成功後會產生下列 Cookies
使用 Access Token 呼叫 Web API
在 Startup
中,如果有設定 SaveTokens = true
,會把 Token 存在 Cookie 裡
1 | if (User.Identity.IsAuthenticated) |