one time password in j2me application - java-me

I am working on an j2me application, where the users can set password only once and it should be the password through out the application life.
It is not password for each user, it is password of application, where I need to store only once.
How to set this password using database?

Will your database be on the phone? If so, you can use a RecordStore. A good article on it is http://developers.sun.com/mobility/midp/articles/databasemap/
You can use a Simple Object Mapping to store your users login and password like:
class User {
private String login, password;
// ... constructors, setters and getters
public byte[] toByteArray() throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream( bout );
dout.writeUTF( login );
dout.writeUTF( password );
dout.close();
return bout.toByteArray();
}
// fromByteArray method
}
For each new user you add a new entry to the RecordStore, but never changes or delete content from the RecordStore.
Update after comments.
You can use another Simple Object Mapping to store your application password like:
class ApplicationPassword {
private String password;
// ... constructors, setter and getter
public byte[] toByteArray() throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream( bout );
dout.writeUTF( password );
dout.close();
return bout.toByteArray();
}
// fromByteArray method
}
You must write the returned byte array at your RecordStore only if the recordstore was just created.

Related

Servicestack - Authentication questions

I am currently fighting a bit with my custom CredentialsAuthProvider implementation. First it is important to say, that I am writing a WPF client as a reference for my API.
A browser stores cookies and you can configure how to deal with them, e.g. delete when the browser is closed. On windows desktop you have Environment.SpecialFolder.Cookies where Windows stores cookies. But I could not find anything from ServiceStack. So does it not store anything on a Windows Desktop app? I saw there is a client.CookieContainer where I find three cookies after login.
Can I somehow add properties to this cookie during Authentication? If so how? Currently I use AuthenticationResponse.MetaDictionary to transfer additional information:
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
{
var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request);
authResponse.Meta = new Dictionary<string, string>();
authResponse.Meta.Add("Test", "TestValue");
return authResponse;
}
And finally: Is an instance of my derived CredentialsAuthProvider class thread safe? In TryAuthenticate(...) I make a DB connection and retrieve an object which contains all information including hashed password etc. But I can only fill this information to the session object in OnAuthenticated(....) and/or overridden Authenticate(...). If possible I do not want to make another DB call to retrieve the same object again. So is it safe to declare a member user fill it in TryAuthenticate and reuse it in other overwritten methods like so:
public class BediCredentialsAuthProvider : CredentialsAuthProvider
{
private AppUser user = null;
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
{
var authResponse = (AuthenticateResponse)base.Authenticate(authService, session, request);
authResponse.Meta = new Dictionary<string, string>();
authResponse.Meta.Add("ValueA", user.ValueA);
// ... add more properties from user object
return authResponse;
}
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
AppUser user = null;
using (var session = NhSessionFactories.OpenSession(TopinConstants.TopInDbFactory))
{
using (var transaction = session.BeginTransaction())
{
try
{
var appUserRepo = new AccountManagementRepository(session);
user = appUserRepo.GetAppUser(userName); // get user from database using NHibernate
transaction.Commit();
session.Close();
}
catch (Exception ex)
{
Log.Error($"Error retrieving user {user} to authenticate. Error: {ex}");
throw;
}
}
}
// do some logic to test passed credentials and return true or false
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens,
Dictionary<string, string> authInfo)
{
session.DisplayName = user.DisplayName;
session.FirstName = user.Firstname;
session.LastName = user.Lastname;
session.Email = user.EmailAddress;
// etc.....
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
}
You can populate ServiceStack Service Client Cookies just like you would a browser except it only retains permanent Session Ids where you'll need to authenticate with RememberMe=true, e.g:
var response = client.Post(new Authenticate {
provider = "credentials",
UserName = ...,
Password = ...,
RememberMe = true,
});
Which will save the Authenticated User Session against the ss-pid permanent Cookie in the HttpWebRequest CookieContainer and gets sent on every subsequent request.
You can set your own Permanent Cookies in OnAuthenticated from authService with:
var httpRes = authService.Request.Response;
httpRes.SetPermanentCookie(cookieName, cookieValue);
Is an instance of my derived CredentialsAuthProvider class thread safe?
No the same AuthProvider singleton instance is used to Authenticate each request so you can't maintain any stored variables on the instance itself and will need to remove:
//private AppUser user = null; //Instance variables are not ThreadSafe
If you want to pass items and access them throughout the Request Pipeline you can store them in IRequest.Items Dictionary, e.g:
authService.Request.Items["AppUser"] = user;

ServiceStack Custom Credentials Auth with DB Stored Api Keys

Right now, we're authenticating our users with this:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
}
Which works great when using the JsonServiceClient.
We have some legacy code written in Visual FoxPro which wants to call some of the authenticated functions in ServiceStack... to accommodate this, we'd like to also allow Api Keys. We want the API Keys to be stored in SQL Server to avoid issues if the process stops / restarts. So, the client would authenticate with domain credentials, then generate an API key for subsequent calls which would be stored in the database (ideally just using the table servicestack can create (dbo.ApiKey).
If we were to set this per the docs:
container.Register<IAuthRepository>(c => new OrmLiteAuthRepository(dbFactory));
We get an error on the OnAuthenticated function above telling us we should call Init()... like its trying to also create the user tables. So I'm not sure how to allow DB stored API Keys, along with custom authentication that relies on both active directory as well as our custom tables for users and roles.
Instead of inheriting from CredentialsAuthProvider, maybe its better to register a custom IUserAuthRepository and IManageRoles?
The API Key AuthProvider needs to be registered in your AuthFeature, e.g:
Plugins.Add(new AuthFeature(...,
new IAuthProvider[] {
new ApiKeyAuthProvider(AppSettings),
new WindowsAuthProvider(AppSettings),
//...
}));
Which requires a IAuthRepository like you're doing:
container.Register<IAuthRepository>(c =>
new OrmLiteAuthRepository(dbFactory));
Any AuthProvider that requires creating a back-end tables or other schema requires that its schema is initialized on Startup which you can do with:
container.Resolve<IAuthRepository>().InitSchema();
It's safe to always call InitSchema() as it only creates missing tables or is otherwise ignored for AuthRepositories that don't require creating a schema.
An issue you're running into is that you've registered an IAuthRepository and are inheriting a CredentialsAuthProvider which you don't want to use it in so you can't call CredentialsAuthProvider.OnAuthenticated() since it will save the User Auth info to the repository if it exists.
So you'll need to provide a custom implement without calling base.OnAuthenticated(), e.g:
public class WindowsAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "OurDomain"))
{
// TODO make sure user record exists in custom DB tables as well
return pc.ValidateCredentials(userName, password);
}
}
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
try
{
session.IsAuthenticated = true;
session.OnAuthenticated(authService, session, tokens, authInfo);
AuthEvents.OnAuthenticated(authService.Request, session, authService, tokens, authInfo);
}
finally
{
this.SaveSession(authService, session, SessionExpiry);
}
return null;
}
}

Tyrus - pass object from client to server

Is it posible to pass custom object from client to server, using Tyrus project for websocket communication. I want to build simple desktop application using JavaFX. How can I pass data that I "collect" on client side (e.g. Object Person with name and lastname fields) so I can save that data to database (on my server logic) ?
It is possible and the form of transferred data is completely your choice.
WebSocket can transfer text or binary data, that's it. You can serialize your obect to ObjectStream and send the data as binary stream, or You can use use JAXB to marshall and umarshall data to/from XML, or JSON-P for JSON (note that there are lots of other possibilities, like GSON, Jackson, ...).
If I would be in your position, I'd use JSON with whatever library I find usable - this way, when you'll extend the application scope to javascript clients, you'll be able to reuse (hopefully) everything.
In addition to Pavel Bucek explanation, sample code is here
Base64 for conversion
import java.util.Base64;
Serverendpoint
ArrayList listobj=new ArrayList();
listobj.add("data1");
listobj.add("data2");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(listobj);
String str = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
session.getBasicRemote().sendText(str);
Client (Tyrus)
#OnMessage
public void onMessage(Session session, final String message) throws IOException {
try {
byte data[] = Base64.getDecoder().decode(message);
bis = new ByteArrayInputStream(data);
ois = new ObjectInputStream(bis);
ArrayList list= (ArrayList) ois.readObject();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
} catch (Exception e) {
System.out.println("error : " + e.getMessage());
} finally {
if (bis != null) {
bis.close();
}
if (ois != null) {
ois.close();
}
}
}

Why can't I log in as the seeded user?

I'm working on a new ASP.NET MVC project, using individual accounts stored in the database for authentication. Here's my class that will seed the database with sample data every time I test:
public class DevelopmentInitializer : DropCreateDatabaseAlways<ApplicationDbContext>
{
protected override void Seed(ApplicationDbContext context)
{
base.Seed(context);
var applicationUserManager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));
var sampleUserOne = new ApplicationUser { UserName = "SampleUser", Email = "sample#example.com" };
var result = applicationUserManager.Create(sampleUserOne, "aaaaaa");
if (!result.Succeeded)
throw new Exception();
context.SaveChanges();
}
}
The Login action is as it is in the template:
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
The description of problem is very simple: Trying to log in using the seeded user's credentials fails.
Specifically, the FindAsync method returns null, even though the user is present in the database - FindByEmailAsync does find the seeded user.
However, creating a new account works and allows me to log in.
Why can't I log in as the seeded user, even though I can register a new account and log in using that?
I'm suspecting it has to do with how the passwords are hashed, but I don't know how to confirm this.
Am I seeding the account wrong? Should I not be creating a separate ApplicationUserManager in the Seed method? If not, how should I get one in order to call Create? I'm trying to understand how the new system works, before ending up locked out of my account or the users end up locked out of theirs in a deployed application.
The following code:
var user = await UserManager.FindAsync(model.Email, model.Password);
is expecting the userName to be passed in, not the email address.
This simple change should take care of things:
var user = await UserManager.FindAsync(model.UserName, model.Password);
If you see the definition of PasswordSignInAsync, it requires the username string and not the email. Maybe the reason why the UI for login ask for email is because of the autogenerated code where the email would be equal to username inside the controller.

Populating IAuthSession with data from the database

So I've created a custom CredentialsAuthProvider using ServiceStack as per the examples located here:
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
I have the authentication side of things working but I'm not sure how I populate the session with data from the database in the OnAuthenticated method. In the example they show the following:
//Fill the IAuthSession with data which you want to retrieve in the app eg:
session.FirstName = "some_firstname_from_db";
In the TryAuthenticate method I have the username/password, which I can use to authenticate the user against the database, but once it goes to the OnAuthenticated method, how/what do I use to access/retrieve the user information from the database?
I know this is an older thread but it may still be relevant because unfortunately not much has improved since Sep of 2012 in terms of availability of ServiceStack documentation, clarity of examples or even comments in the code. (#mythz: It would be very helpful if you guys could add meaningful summaries to all your classes and methods.)
I struggled with the same dilemma until I looked at the actual code of CredentialsAuthProvider (which in general is pretty much the only way to understand how things work in ServiceStack). The OnAuthenticated is called right after TryAuthenticate inside the Authenticate method, so I figured it's not necessary to make all your DB calls in OnAuthenticated as #mythz suggests in his examples. Instead I placed the code that populates the IAuthSession object right into my implementation of TryAuthenticate, like so:
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
try
{
// Use my own repo to authenticate the user.
var userRepo = authService.TryResolve<IUserRepository>();
var user = userRepo.Authenticate(userName, password);
// Populate session properties with data from my user POCO.
var session = authService.GetSession();
session.Id = user.CurrentSession.ID.ToString();
session.IsAuthenticated = true;
session.CreatedAt = DateTime.UtcNow;
session.DisplayName = session.FirstName = session.LastName = user.FullName;
session.UserAuthName = session.UserName = user.Username;
session.UserAuthId = user.ID.ToString();
}
catch (Exception ex)
{
// Log the exception, etc....
return false;
}
return true;
}
However, you still have to override OnAuthenticated in order to save the cookie in HTTP response (which I assume is required for subsequent requests from the same browser to be authenticated) because the base implementation only sets the cookie if it finds IUserAuthRepository in the IOC container, which in my case won't happen because I use my own repository. So my implementation now looks like this:
public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo)
{
try
{
// Save the browser cookie.
var httpRes = authService.RequestContext.Get<IHttpResponse>();
if (httpRes != null)
{
httpRes.Cookies.AddPermanentCookie(HttpHeaders.XUserAuthId, session.UserAuthId);
}
// Save the user session object (ServiceStack stores it in the in-memory cache).
authService.SaveSession(session, SessionExpiry);
}
catch (Exception ex)
{
// Log the exception, etc....
}
}
#mythz: Please let me know if the above makes sense or not.
Another good example of a ServiceStack's CustomUserSession is in the SocialBootstrapApi project. Rather than pulling information out of the data, it extracts the information out of the UserSession and populates its own Custom User Table using the registered DB Factory resolved from the AppHost IOC:
authService.TryResolve<IDbConnectionFactory>().Run(db => db.Save(user));
Rather than using it to extract and save data from the user's session, you can also use any of your registered dependencies to fetch data and populate the session with:
public override void OnAuthenticated(
IServiceBase authService,
IAuthSession session,
IOAuthTokens tokens,
Dictionary<string, string> authInfo)
{
using (var db = authService.TryResolve<IDbConnectionFactory>().OpenDbConnection())
{
var user = db.Id<MyUser>(session.UserId);
session.FirstName = user.FirstName;
}
}

Resources