Login module in Titanium - authentication

Any one has experience in development of Login module with ProviderService.Src.
I need to develop a login module with the webservice using Titanium Appcelerator. It needs to take two strings (Username & Password) and return true/false. I need to send entered login and password via web service and receive true/false. The webservice is
http://46.18.8.42/FareBids.Service/FareBids.ServiceLayer.ProviderService.svc
Please some one guide me how to create a Login module with it? I got information which says me to use SUDS. Can some one help me on this with code(if possible)
Help would really be appreciated. Thanks.

Use a webservice http client. This should do it, you will have to tune this to your specific webservice and obviously collect data from the user, but how to do that is well documented in the most basic Titanium tutorials.
var loginSrv = Ti.Network.createHTTPClient({
onload : function(e) {
// If the service returns successfully : true, or false
var isUserAllowed = this.responseText;
},
onerror : function(e) {
// Web service failed for some reason
Ti.API.info(this.responseText);
Ti.API.info('webservice failed with message : ' + e.error);
}
});
loginSrv.open('POST', 'http://46.18.8.42/FareBids.Service/FareBids.ServiceLayer.ProviderService.svc');
// you may have to change the content type depending on your service
loginSrv.setRequestHeader("Content-Type", "application/json");
var sendObj = {loginid : 'someid', pwd : 'somepassword'};
loginSrv.send(obj);

Related

Windows authentication fail with "401 Unauthorized"

I have a MVC client accessing a Web API protected by IDS4. They all run on my local machine and hosted by IIS. The app works fine when using local identity for authentication. But when I try to use Windows authentication, I keep getting "401 Unauthorized" error from the dev tool and the login box keeps coming back to the browser.
Here is the Windows Authentication IIS setting
and enabled providers
It's almost like that the user ID or password was wrong, but that's nearly impossible because that's the domain user ID and password I use for logging into the system all the time. Besides, according to my reading, Windows Authentication is supposed to be "automatic", which means I will be authenticated silently without a login box in the first place.
Update
I enabled the IIS request tracing and here is the result from the log:
As you can see from the trace log item #29, the authentication (with the user ID I typed in, "DOM\Jack.Backer") was successful. However, some authorization item (#48) failed after that. And here is the detail of the failed item:
What's interesting is that the ErrorCode says that the operation (whatever it is) completed successfully, but still I received a warning with a HttpStatus=401 and a HttpReason=Unauthorized. Apparently, this is what failed my Windows Authentication. But what is this authorization about and how do I fix it?
In case anyone interested - I finally figured this one out. It is because the code that I downloaded from IndentityServer4's quickstart site in late 2020 doesn't have some of the important pieces needed for Windows authentication. Here is what I had to add to the Challenge function of the ExternalController class
and here is the ProcessWindowsLoginAsync function
private async Task<IActionResult> ProcessWindowsLoginAsync(string returnUrl)
{
var result = await HttpContext.AuthenticateAsync(AccountOptions.WindowsAuthenticationSchemeName);
if (result?.Principal is WindowsPrincipal wp)
{
var props = new AuthenticationProperties()
{
RedirectUri = Url.Action(nameof(Callback)),
Items =
{
{ "returnUrl", returnUrl },
{ "scheme", AccountOptions.WindowsAuthenticationSchemeName },
}
};
var id = new ClaimsIdentity(AccountOptions.WindowsAuthenticationSchemeName);
id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
if (AccountOptions.IncludeWindowsGroups)
{
var wi = wp.Identity as WindowsIdentity;
var groups = wi.Groups.Translate(typeof(NTAccount));
var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value));
id.AddClaims(roles);
}
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
return Redirect(props.RedirectUri);
}
else
{
return Challenge(AccountOptions.WindowsAuthenticationSchemeName);
}
}
Now my windows authentication works with no issues.

Authentication Service throws Procedure invocation error post upgrade from MFP 6.3 to MFP 7.1

Authentication adapter throwing "Procedure invocation error" sometimes. Tried clearing cache and cookies but still the same. So we tried to login from different system for same user and it works. This is quite confusing as once we try with different ID in browser where issue occurred, it works and then it works with Member ID which has issue as well. Auth required is not coming in response when issue occurs.
we have tried to look into logs and found WorklightAuthenticationException from Authentication Adapter while trying security test procedure.
Authentication Adapter code:
var result = WL.Server.invokeHttp(input);
WL.Logger.info("Authentication service : " + JSON.stringify(result));
authResponse = prepareJSONResponse(result,channelId);
WL.Logger.info('Formatted response -> ' + JSON.stringify(authResponse));
if(result.isSuccessful == false){
WL.Logger.info("Error: " + result.errorMessage);
return onAuthRequired(null, "Error in connecting to server. Please try again later.");
}
if(typeof authResponse.errorMessage != 'undefined'){
WL.Logger.info("Error is defined" +authResponse.errorMessage);
return onAuthRequired(null, authResponse);
}
WL.Logger.info("Authentication service success: " + JSON.stringify(result));
WL.Logger.info("userIdentity Parameters: " + inputParams.CorpId);
var userIdentity = {
userId: inputParams.CorpId,
displayName: inputParams.CorpId,
attributes: {
foo: "bar"
}
};
WL.Logger.info("userIdentity::"+JSON.stringify(userIdentity));
WL.Server.setActiveUser("SingleStepAuthRealm", userIdentity);
return {
authRequired: false
};
It is happening due to the requests going from one node to another node. Handled it in Load balancer to send requests to specific node based on cookies and post that it works fine.
The description mentions about clearing cache and cookies and using browser.
Browser based environments are not supported in session independent mode. These work only in session dependent mode. As such, it is imperative that session based affinity be enabled to ensure the requests land in the same JVM for authentication state to be preserved.
More details can be found here : Session-independent mode

IBM Worklight : WL.Client.getUserName Fails to retrieve userIdentity immediately after authentication

I have done adapter based authentication and there is no problem in authentication and it works fine. I have faced some issues in getting the active users useridentity.The code may explain you a bit more
adapterAuthRealmChallengeHandler.handleChallenge = function(response){
var authRequired = response.responseJSON.authRequired;
if (authRequired == true){
if (response.responseJSON.errorMessage)
alert(response.responseJSON.errorMessage);
} else if (authRequired == false){
adapterAuthRealmChallengeHandler.submitSuccess();
setTimeout(function(){pageTransitionCall();},10000); //this code only works
pageTransitionCall(); //This throws null error in console
}
};
function pageTransitionCall(){
console.log(WL.Client.getUserName("AdapterAuthRealm"));
}
As you can see i was trying to get the active userName of the realm. The WL.Client.getUserName("AdapterAuthRealm") only works after some time interval only and i am not sure about the time interval. By adapter code is as below
function submitAuthentication(username, password,userCred){
if (username==="worklight" && password === "worklight"){
WL.Logger.info("if");
var userIdentity = {
userId: userCred,
displayName: userCred,
attributes: {
foo: "bar"
},
loginName : userCred,
userName : userCred
};
WL.Server.setActiveUser("AdapterAuthRealm", userIdentity);
WL.Logger.info(JSON.stringify(userIdentity));
return {
authRequired: false
};
}
else
{
WL.Logger.info("else");
return onAuthRequired(null, "Invalid login credentials");
}
}
My doubt is why does the client cant retrieve the activeuser. And i am sure that my code is correct and active user is set and i can see in the server log.After the setactvieruser is set only i have return false in the adpter and why cant the client retrieve the user at instant and why it needs delay to retrieve. i have verified in both Worklight V6.0 and also Worklight V6.1.i have created the Ipad environment.
The info that contains logged in userId (basically any userIdentity data) is not returned immediately after adapter authentication but only when an original request succeeds. Consider this
You're making request#1 to the server (let's say invoke procedure)
You're getting response with authRequired:true
You're submitting auth data
You're getting authRequred:false
You're calling submitSuccess()
WL framework automatically re-invokes request#1
You're getting response for request#1
userIdentity data will be returned in step7 and not in step4. Basically once you start authentication flow you're considered out of the original invocation context. You need to finish the flow and tell WL framework that auth has completed. Once you do - WL framework will reinvoke the original request. WL server add userIdentity data to the response and WL client will update userName, displayName etc properties.
In case you need user data before that, e.g. right away once auth is complete, you can add custom properties to your submitAuthentication function response, e.g.
WL.Server.setActiveUser("AdapterAuthRealm", userIdentity);
return {
authRequired: false,
loginName: userIdentity.loginName
};
this will make sure that loginName will be returned to your handleChallenge function. you can retrieve it there and do whatever you want with it.

disconnect client from server side signalr

I'm using SignalR 1 with MVC4 C# web application with form authentication.
I have a code in my layout page in JavaScript :
$(documnet).ready(function(){
connect to hub code ...
})
I want to disconnect a user form the hub and start connect again after he does a login and validate ok.
I want to do it from server side inside my account controller and method :
public ActionResult LogOn(LoginModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
....here , disconnect from hub
....to make the user reconnect
}
The reason I want to do it is because SignalR throws an error if user changed to authenticated after login and the connection remains . The error is:
The connection id is in the incorrect format.
You cannot stop and start SignalR connections from the server. You will need to call
$.connection.hub.stop(); //on the client before the user attempts to log on and then call
$.connection.hub.start(); //after the log on attempt has completed.
One way you could do what you ask is to write a disconnect event on your client that the server can call through SignalR. Maybe something somewhat like this:
myHub.client.serverOrderedDisconnect = function (value) {
$.connection.hub.stop();
};
Then, on the server, something like this:
Clients.Client(Context.ConnectionId).serverOrderedDisconnect();
If someone is still looking for solution(SignalR version 2.4.1):
GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>().GetConnections().First(c => c.ConnectionId == "YourId").Disconnect();
Try controlling everything from javascript. The following is a logout example, login would be similar.
From http://www.asp.net/signalr/overview/security/introduction-to-security:
If a user's authentication status changes while an active connection
exists, the user will receive an error that states, "The user identity
cannot change during an active SignalR connection." In that case, your
application should re-connect to the server to make sure the
connection id and username are coordinated. For example, if your
application allows the user to log out while an active connection
exists, the username for the connection will no longer match the name
that is passed in for the next request. You will want to stop the
connection before the user logs out, and then restart it.
However, it is important to note that most applications will not need
to manually stop and start the connection. If your application
redirects users to a separate page after logging out, such as the
default behavior in a Web Forms application or MVC application, or
refreshes the current page after logging out, the active connection is
automatically disconnected and does not require any additional action.
The following example shows how to stop and start a connection when
the user status has changed.
<script type="text/javascript">
$(function () {
var chat = $.connection.sampleHub;
$.connection.hub.start().done(function () {
$('#logoutbutton').click(function () {
chat.connection.stop();
$.ajax({
url: "Services/SampleWebService.svc/LogOut",
type: "POST"
}).done(function () {
chat.connection.start();
});
});
});
});
You can the hub context to abort() the connection directly in .Net Core
Context.Abort();
See the method below
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.signalr.hubcallercontext.abort
Try this:
public ActionResult LogOn(LoginModel model, string returnUrl) {
if (ModelState.IsValid) {
if (System.Web.Security.Membership.ValidateUser(model.UserName, model.Password)) {
FormsAuthentication.SetAuthCookie(model.UserName, false);
connection.Stop();
}
}
Assuming your connection handle is connection. The challenge is accessing a handle to your connection object in your Action Method.
Copy and paste the following function into your Hub
Use HttpContext.Current.Response.End();
to force the client to disconnect in your hub

How to pass authorization code from JSP to Servlet

I am at my wits end, 7 hours and counting.
I am new to FB development and am having an issue of passing the authorization code from my JSP to my Servlet.
1.) I use the social plugin for login in my JSP as shown below
<fb:login-button>Login with Facebook</fb:login-button>
This logs the user in and allows them to grant my app access to their personal information
2.) Once login and authorization are successful, the user is forwarded to my servlet from the JSP via the code below
FB.Event.subscribe('auth.login', function (response) {
window.location = "testservlet";
});
3.) But when I attempt to get the authorization code (so that I can get the auth. token) in my Servlet, the "code" is empty, see the code I am using to retrieve below
String authCode = req.getParameter("code");
Can anyone tell me what I am doing wrong? I am sure that I am missing something so simple..or am trying to do more than is necessary, thanks in advance
I am not familiar with Facebook dev, but concerning servlets, window.location normally speaking will not take you to a servlet.
try using jquery's ajax function and pass a "code" parameter. Do something like :
$.ajax({
url: yourServletPath+"testservlet",
data:"code="+codevariable,
dataType: "whatever data type your servlet returns",
success: function(response)
{
// wtv code to be done
}
});