ASP. net mvc sso Single Sign-on design and implementation code, mvcsso

Source: Internet
Author: User

ASP. net mvc sso Single Sign-on design and implementation code, mvcsso

Lab environment Configuration

The HOST file is configured as follows:

127.0.0.1 app.com
127.0.0.1 sso.com

The IIS configuration is as follows:

The application pool uses. Net Framework 4.0

Note that the domain name bound to IIS is two domain names that are completely different from each other.

The website configuration for app.com is as follows:

 

The sso.com website configuration is as follows:

Memcached cache:

Database Configuration:

The database uses EntityFramework 6.0.0. When it is run for the first time, the corresponding database and table structure will be automatically created.

Authorization verification process Demonstration:

Access the: http://app.com in the browser's address bar and the website will be automatically redirected to: login if the user has not logged in:

URL: http://sso.com/passport? Appkey = 670b14728ad9902aecba32e22fa4f6bd & username =

After you enter the correct Logon account and password, click the login button and the system will automatically redirect 301 to the application's homepage. After the successful destruction, the system will see the following:

Because SSO authorization login is performed in different domains, the QueryString method is used to return the authorization ID. The Cookie method can be used for the same network site. Because the 301 redirection request is sent by the browser, if the authorization ID is put into Handers, the browser will lose the redirection. After successful redirection, the program automatically writes the authorization identifier to the Cookie. When you click another page address, the authorization identifier information will no longer be displayed in the URL address bar. Cookie settings are as follows:

Subsequent authorization verification after successful login (access to other pages that require authorized access ):

Check address: http://sso.com/api/passport? Sessionkey = xxxxxx & remark = xxxxxx

Returned results: true, false

The client prompts that the user's authorization has been lost and needs to be re-authorized based on the actual business situation. The default automatic redirect to SSO login page, that is: http://sso.com/passport? Appkey = 670b14728ad9902aecba32e22fa4f6bd & username = seo@ljja.cn at the same time login page mailbox address text box will be customized to complete the user's login account, the user just enter the login password, after successful authorization session validity period automatically extended for one year.

SSO database verification log:

User authorization verification log:

User-authorized Session:

Database User Account and application information:

Core code of the application authorization login verification page:

/// <Summary> /// public Key: AppKey /// private key: AppSecret /// session: SessionKey /// </summary> public class PassportController: controller {private readonly IAppInfoService _ appInfoService = new AppInfoService (); private readonly IAppUserService _ appUserService = new AppUserService (); private readonly IUserAuthSessionService _ authSessionService = new UserAuthSessionService (); private readonly extends Ice _ userAuthOperateService = new UserAuthOperateService (); private const string AppInfo = "AppInfo"; private const string SessionKey = "SessionKey"; private const string SessionUserName = "SessionUserName "; // default logon interface public ActionResult Index (string appKey = "", string username = "") {TempData [AppInfo] = _ appInfoService. get (appKey); var viewModel = new PassportLoginRequest {AppKey = appKey, User Name = username}; return View (viewModel);} // authorize logon to [HttpPost] public ActionResult Index (PassportLoginRequest model) {// obtain application information var appInfo = _ appInfoService. get (model. appKey); if (appInfo = null) {// return View (model) does not exist in the application;} TempData [AppInfo] = appInfo; if (ModelState. isValid = false) {// return View (model);} // The model character is invalid in the filter field. trim (); // obtain the user information var userInfo = _ appUserService. get (model. UserName); if (userInfo = null) {// return View (model) does not exist for the user;} if (userInfo. UserPwd! = Model. password. toMd5 () {// incorrect password return View (model);} // obtain the Session var currentSession = _ authSessionService that has not expired. existsByValid (appInfo. appKey, userInfo. userName); if (currentSession = null) {// construct Session currentSession = new UserAuthSession {AppKey = appInfo. appKey, CreateTime = DateTime. now, InvalidTime = DateTime. now. addYears (1), IpAddress = Request. userHostAddress, SessionKey = Guid. newGui D (). toString (). toMd5 (), UserName = userInfo. userName}; // create Session _ authSessionService. create (currentSession);} else {// extend the validity period. The default value is one year _ authSessionService. extendValid (currentSession. sessionKey);} // record user authorization log _ userAuthOperateService. create (new UserAuthOperate {CreateTime = DateTime. now, IpAddress = Request. userHostAddress, Remark = string. format ("{0} login {1} authorization successful", currentSession. userName, appInfo. T Itle), SessionKey = currentSession. SessionKey}); 104 var redirectUrl = string. Format ("{0 }? SessionKey = {1} & SessionUserName = {2} ", appInfo. returnUrl, currentSession. sessionKey, userInfo. userName); // jump to the default callback page return Redirect (redirectUrl) ;}} Memcached session ID verification core code: public class PassportController: apiController {private readonly IUserAuthSessionService _ authSessionService = new UserAuthSessionService (); private readonly container _ userAuthOperateService = new container (); public bool Get (string sessionKey = "", string remark = "") {if (_ authSessionService. getCache (sessionKey) {_ userAuthOperateService. create (new UserAuthOperate {CreateTime = DateTime. now, IpAddress = Request. requestUri. host, Remark = string. format ("verified-{0}", remark), SessionKey = sessionKey}); return true;} _ userAuthOperateService. create (new UserAuthOperate {CreateTime = DateTime. now, IpAddress = Request. requestUri. host, Remark = string. format ("Verification Failed-{0}", remark), SessionKey = sessionKey}); return false ;}}

Client Authorization verification Filters Attribute

Public class SSOAuthAttribute: ActionFilterAttribute {public const string SessionKey = "SessionKey"; public const string SessionUserName = "SessionUserName"; public override void OnActionExecuting (ActionExecutingContext filterContext) {var Limit = ""; var cookieSessionUserName = ""; // SessionKey by QueryString if (filterContext. httpContext. request. queryString [SessionKey]! = Null) {cookieSessionkey = filterContext. httpContext. request. queryString [SessionKey]; filterContext. httpContext. response. cookies. add (new HttpCookie (SessionKey, cookieSessionkey);} // SessionUserName by QueryString if (filterContext. httpContext. request. queryString [SessionUserName]! = Null) {cookieSessionUserName = filterContext. httpContext. request. queryString [SessionUserName]; filterContext. httpContext. response. cookies. add (new HttpCookie (SessionUserName, cookieSessionUserName);} // read SessionKey if (filterContext. httpContext. request. cookies [SessionKey]! = Null) {cookieSessionkey = filterContext. HttpContext. Request. Cookies [SessionKey]. Value;} // read SessionUserName if (filterContext. HttpContext. Request. Cookies [SessionUserName] From the Cookie. = Null) {cookieSessionUserName = filterContext. httpContext. request. cookies [SessionUserName]. value;} if (string. isNullOrEmpty (cookieSessionkey) | string. isNullOrEmpty (cookieSessionUserName) {// directly log on to filterContext. result = SsoLoginResult (cookieSessionUserName);} else {// verify if (CheckLogin (cookieSessionkey, filterContext. httpContext. request. rawUrl) = false) {// session loss, jump to the login page filterContext. result = SsoLoginResult (cookieSessionUserName) ;}} base. onActionExecuting (filterContext);} public static bool CheckLogin (string sessionKey, string remark = "") {var httpClient = new HttpClient {BaseAddress = new Uri (ConfigurationManager. appSettings ["SSOPassport"])}; var requestUri = string. format ("api/Passport? SessionKey = {0} & remark = {1} ", sessionKey, remark); try {var resp = httpClient. getAsync (requestUri ). result; resp. ensureSuccessStatusCode (); return resp. content. readAsAsync <bool> (). result;} catch (Exception ex) {throw ex;} private static ActionResult SsoLoginResult (string username) {return new RedirectResult (string. format ("{0}/passport? Appkey = {1} & username = {2} ", ConfigurationManager. configurettings [" SSOPassport "], ConfigurationManager. configurettings [" SSOAppKey "], username ));}}

Sample SSO verification feature usage:

[SSOAuth]  public class HomeController : Controller  {    public ActionResult Index()    {      return View();    }    public ActionResult About()    {      ViewBag.Message = "Your application description page.";      return View();    }    public ActionResult Contact()    {      ViewBag.Message = "Your contact page.";      return View();    }  }

Summary:

From the sample code of the draft, we can see that there are many optimizations in the code performance, as well as a series of prompts such as the absence of user accounts on the Authorization login page of the SSO application, and incorrect passwords. After the Business Code runs properly, you can consider optimizing it to more security levels, such as enabling AppSecret Private Key signature verification and IP Range verification, fixed Session Request attacks, verification code on the SSO authorized login interface, automatic rebuilding of session cache, SSo server, horizontal scaling of cache, etc.

Source Code address: http://xiazai.jb51.net/201701/yuanma/SmartSSO_jb51.rar

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.