5

I have an single page mvc application that works with angular js. Angular calls api from my asp mvc application including the login. I want to add single sign on to my application

My angular check "GetUserRoles" function before transferring to the local login page ..

What I am doing wrong, so the line HttpContext.Current.GetOwinContext().Authentication.Challenge() in UserAccountApiController does not open adfs sso page ???

UserAccountApiController

    [HttpPost]
    public bool IsLogedInRoled(NR role)
    {
        if (User.Identity.IsAuthenticated)
        {
            if (!string.IsNullOrEmpty(role.role))
            {
                var isLogedInRoled = GetUserRoles().Select(x => x.ToLower()).Contains(role.role);
                return isLogedInRoled;
            }
            return true;
        }
        HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "~/" },
            WsFederationAuthenticationDefaults.AuthenticationType);

        return false;

    }

Startup.cs

public class CustomeStartup : UmbracoDefaultOwinStartup
{
    private static string realm = ConfigurationManager.AppSettings["ida:Wtrealm"];
    private static string adfsMetadata = ConfigurationManager.AppSettings["ida:ADFSMetadata"];
    private static string adfsWreply = ConfigurationManager.AppSettings["ida:Wreply"];

    public override void Configuration(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
        app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieName = "E-services" });
        app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
        {
            Wtrealm = realm,
            MetadataAddress = adfsMetadata,
            Notifications = new WsFederationAuthenticationNotifications()
            {
                // this method will be invoked after login succes , for the first login
                SecurityTokenValidated = context =>
                {
                    ClaimsIdentity identity = context.AuthenticationTicket.Identity;
                    // here we can add claims and specify the type, in my case i want to add Role Claim
                    string[] roles = { };
                    roles = NParser.ToDecimal(identity.Name) > 0
                        ? new[] { "Student" }
                        : new[] { "Employee" };
                    identity.AddClaim(new Claim(ClaimTypes.Role, roles.First()));
                    //identity.AddClaim(new Claim(ClaimTypes.Role, "somethingelse"));
                    return Task.FromResult(0);
                },
                RedirectToIdentityProvider = context =>
                {
                    context.ProtocolMessage.Wreply = adfsWreply;
                    return Task.FromResult(0);
                }
            },
        });
        app.UseStageMarker(PipelineStage.Authenticate);
        base.Configuration(app);
    }
}

Web.config

<add key="owin:appStartup" value="CustomeStartup" />
<add key="ida:ADFSMetadata" value="https://udsts.ud.edu.sa/federationmetadata/2007-06/federationmetadata.xml" />
<add key="ida:Wtrealm" value="https://10.31.26.28/" />
<add key="ida:Wreply" value="https://10.31.26.28/" />

auth-guard.service.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from 'app/services/auth/auth.service';

@Injectable()
export class AuthGuardService {
    isloggedIn = false;
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const absorver =
            this.auth
                .checkLogedinRole(route.data)
                .take(1);

        absorver.toPromise().then(x => {
            this.isloggedIn = x;
            if (!x) {
                this.router.navigate(['login']);
            }
        });
        return absorver;
    }
    constructor(private router: Router, private auth: AuthService) { }
}

auth.service.ts

    public checkLogedinRole(role: object): Observable<any> {
        const url = '/umbraco/api/UserAccountApi/IsLogedInRoled';
        return this.http.post(url, role)
            .map(x => x.json())
            .catch(this._httpService.handleError);
    }
    public login(model: LoginModel): Observable<boolean> {
        const status = false;

        const headers = new Headers({ 'Access-Control-Allow-Origin': '*' });
        const options = new RequestOptions({ headers: headers });

        const obs = this.http.post('/umbraco/api/UserAccountApi/login', model, options)
            .map(x => x.json())
            .catch(this._httpService.handleError);

        return obs;

    }
Wassan
  • 51
  • 1
  • 1
  • 4

1 Answers1

5

Please remove current from below code in your UserAccountApiController

 Old - HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "~/" },
           WsFederationAuthenticationDefaults.AuthenticationType);

New - HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "~/" },
           WsFederationAuthenticationDefaults.AuthenticationType);

OWIN has its own version of an authentication manager in the IAuthenticationManager interface which is attached to the HttpContext object.This object handles creation and deleting of the secure cookie that is used to track the user through the site. The identity cookie is used to track all logged in users, regardless of whether they logged in locally with a username and password or using an external provider like Google. Once a user is authenticated, the SignIn method is called to create the cookie. On subsequent requests, OWIN based Identity subsystem then picks up the Cookie and authorizes the user the appropriate IPrinciple (a ClaimsPrinciple with a ClaimsIdentity) based User whenever the user accesses your site.

Rahul Singh
  • 918
  • 14
  • 31
Anonymous
  • 51
  • 1
  • 2
    my controller is inherited from UmbracoApiController which is an ApiController, which means that I couldn't get the HttpContext as in a Controller inherited class. What can I do ? – Wassan May 14 '19 at 10:05
  • Check this link - https://dotronald.be/add-azure-active-directory-to-an-existing-asp-net-mvc-web-application/ – Anonymous May 17 '19 at 04:51
  • 2
    that link doesnt address he is extending a ApiController – Ricardo Saracino Nov 23 '19 at 15:43
  • The "New" line above gives me the compile error: CS0117 'HttpContext' does not contain a definition for 'GetOwinContext' – Mike W Oct 24 '22 at 13:56