JBoss5でユーザー認証(BASIC認証・DIGEST認証・FORM認証)を行う
WEBアプリでサーバーにユーザ認証をまかせるとき、TomcatとJBossとではサーバー側の設定が少し異なる。
JBossのバージョン情報:
Name: JBoss SOA-P 5 (development)
Version: 5.3.0.GA
Description: JBoss Enterprise SOA Platform
設定すべきファイルは以下の4つ
JBoss側の設定ファイル
1.sample-ds.xml(sample部は任意)
datasouce(例えば、データベース)への接続方法を記述
2.login-config.xml
1.のdatasourceを利用した認証方法を記述
WEBアプリ側の設定ファイル
3.jboss-web.xml
2.との接続を記述
4.web.xml
認証方法を記述
JBoss側の設定
1.sample-ds.xml(sample部は任意)
$JBOSS_HOME/server/development/deploysample-ds.xml を作成
<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: mysql-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ --> <!-- Datasource config for MySQL using 3.0.9 available from: http://www.mysql.com/downloads/api-jdbc-stable.html --> <datasources> <local-tx-datasource> <jndi-name>sampleDS</jndi-name> <connection-url>jdbc:mysql://mysqldb:3306/sample?autoReconnect=true</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>user</user-name> <password>pass</password> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </local-tx-datasource> </datasources>
「jdbc:mysql://mysqldb:3306/sample?autoReconnect=true」はデータベースのurl
2.login-config.xml
$JBOSS_HOME/server/default/conf/login-config.xml に追記
<application-policy name = "sampleAuth"> <authentication> <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> <module-option name = "dsJndiName">java:/sampleDS</module-option> <module-option name="principalsQuery"> select password from user_info where user_name=? </module-option> <module-option name="rolesQuery"> select role , 'Roles' from user_info where user_name=? </module-option> </login-module> </authentication> </application-policy>
user,passのデータベース作成については下部の参考2を参照(参考2中のrolesQueryの文法に誤りがあるので注意)
テーブルの構成に応じてクエリは変更が必要
WEBアプリ側の設定
3.jboss-web.xml
/WEB-INF/jboss-web.xml を作成
<?xml version="1.0" encoding="UTF-8"?> <jboss-web> <!-- Use the JaasSecurityMgr other security domain for authentication and authorization of secured web content. --> <security-domain>java:/jaas/sampleAuth</security-domain> </jboss-web>
sampleAuthは2.で設定したJNDI
4.web.xml
/WEB-INF/web.xml に追記
<security-constraint> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <url-pattern>/</url-pattern> </web-resource-collection> <auth-constraint> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>User Form Auth</realm-name> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/error.html</form-error-page> </form-login-config> </login-config> <security-role> <role-name>user</role-name> </security-role>
他の認証方式(BASIC認証・DIGEST認証)を利用したい時はauth-methodを変更
参考にしたサイト:
参考1https://access.redhat.com/documentation/ja-JP/JBoss_Enterprise_Application_Platform/5/html/Security_Guide/ch12.html
参考2JBoss各種Tips
pythonによる強調フィルタリング手法GroupLensの実装
レコメンドシステム構築の為、まずは定番のGroupLensの実装を行った。
python(crab)でもR(recommenderlab)でもライブラリはあるようだが、
さして複雑なアルゴリズムではないので、使いこなすより実装した方が早いと判断し、
pythonによる実装を試みた。
アルゴリズムは参考1のP50-56を利用している。
例題も同著の以下のデータを利用。
# -*- coding: utf-8 -*- import numpy as np def pearson(e1,e2): #入力されたリストのうち、どちらともゼロでない要素のみの相関係数を算出 te1=[] te2=[] tmp=np.array(e1)*np.array(e2) for i in range(len(tmp)): if tmp[i]!=0: te1.append(e1[i]) te2.append(e2[i]) if len(te1)==1: return 0 return np.corrcoef(te1,te2)[0,1] def average(e): #入力されたリストのうち、ゼロでない要素のみの平均を算出 n = sum(e) d = len([x for x in e if x!=0]) return n/d def evaluate(a,y,data,arr): #評価推定値を算出 aveA = average(data[a]) d=0 n=0 for i in range(len(data)): if a!=i and data[i][y]!=0:#a自身と、yの評価値がないユーザを除く d+=abs(arr[a][i]) # tmp=np.array(data[a])*np.array(data[i]) # tmp2 = [0 for i in range(len(data[i]))] # for k in range(len(tmp)): # if tmp[k]!=0: # tmp2[k]=data[i][k] # n+=arr[a][i]*(data[i][y]-average(tmp2)) #共通要素以外も含めた平均を利用、上部コメントアウト部分は共通要素を除いた平均を利用した場合 n+=arr[a][i]*(data[i][y]-average(data[i])) return aveA+n/d data = [[0 for i in range(4)] for j in range(4)] arr = [[0 for i in range(4)] for j in range(4)] eva = [[0 for i in range(4)] for j in range(4)] # データの入力 data[0]= [1,3,0,3] data[1]= [0,1,3,0] data[2]= [2,1,3,1] data[3]= [1,3,2,0] # ユーザー間の類似度計算 for key in range(len(data)): base_customers = data[key] for key2 in range(len(data)): if key == key2: continue target_customers = data[key2] j = pearson(base_customers, target_customers) arr[key][key2] = j #ユーザ・商品ごとの評価値推定 for i in range(len(data)): for j in range(len(data[i])): eva[i][j] = evaluate(i,j,data,arr) # ユーザー間の類似度 print(' \t 1 \t 2 \t 3 \t 4 ') print('1\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(arr[0][0], arr[0][1], arr[0][2], arr[0][3])) print('2\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(arr[1][0], arr[1][1], arr[1][2], arr[1][3])) print('3\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(arr[2][0], arr[2][1], arr[2][2], arr[2][3])) print('4\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(arr[3][0], arr[3][1], arr[3][2], arr[3][3])) #ユーザ・商品ごとの評価値推定値 print(' \t 1 \t 2 \t 3 \t 4 ') print('1\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(eva[0][0], eva[0][1], eva[0][2], eva[0][3])) print('2\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(eva[1][0], eva[1][1], eva[1][2], eva[1][3])) print('3\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(eva[2][0], eva[2][1], eva[2][2], eva[2][3])) print('4\t{0:2.2f}\t{1:2.2f}\t{2:2.2f}\t{3:2.2f}'.format(eva[3][0], eva[3][1], eva[3][2], eva[3][3]))
- 実行結果
1 2 3 4 1 0.00 0.00 -1.00 1.00 2 0.00 0.00 1.00 -1.00 3 -1.00 1.00 0.00 -0.50 4 1.00 -1.00 -0.50 0.00 1 2 3 4 1 1.71 3.21 1.71 3.08 2 2.62 1.12 2.62 1.25 3 2.97 0.88 2.42 1.08 4 1.03 2.82 0.92 2.69
以上。
参考1:推薦システムのアルゴリズム
www.kamishima.net/archive/recsysdoc.pdf
消費者来店行動モデルのパラメータ推定(poisson分布)
ここでは実店舗が存在し、商品を販売する小売業を想定している。
このとき消費者の来店間隔はポアソン分布に従うと知られている。(阿部2007)
これは、消費者ごとに毎日一定確率で来店し、それが繰り返されているというモデルである
(来店間隔の最小単位を1日とする。)
「消費者ごと」の一定確率を実績から推定する方法を考えたい。
ポアソン分布のパラメータはλのみであり、これを推定すればよい。
これは期間中の平均来店実績に他ならない。
つまり、来店日数/観測日数 で算出できる
参考:
阿部誠(2007)消費者行動理論にもとづいた個人レベルの RF 分析:階層ベイズによる Pareto/NBD モデルの改良,MMRC Discussion Paper No. 18
Apache Commons VFSでusername,passwordに利用禁止文字を使う方法
String hostName = "US456564" ; String username = "sftpuser@Location"; String password = "Test!@#$%^&*()[]:;"; String localFilePath = "home57556"; FileObject remoteFile = manager.resolveFile( createConnectionString(hostName, username, password, remoteFilePath, fileName), createDefaultOptions());
Apache Commons VFSを利用する際、usernameやpasswordに@等の文字を使うと以下のようなエラーが出てftpにアクセスすることができない。
Caused by: org.apache.commons.vfs2.FileSystemException: Invalid absolute URI "sftp://sftpuser@Location:***@US456564/home57556".
これは内部的には以下のようにアクセスしているためである。
manager.resolveFile("sftp://sftpuser@Location:Test!@#$%^&*()[]:;@US456564/home57556");
この時は、使用できない文字を%○○のようにエンコードしたものを入力するとアクセスができる。
manager.resolveFile("sftp://sftpuser%40Location:Test!%40%23%24%25%5E%26*%5B%5D%3A%3B@US456564/home57556");
eclipseで特定ファイルを除外してwarを作成する(antを利用)
warファイルを作成するにあたって、プロジェクト内のライブラリやgitのリポジトリも一緒にまとめてしまうので、必要以上にサイズが大きくなっていたのでapache-antを使って特定ファイルを除外してwarを作成する方法を調べた。
1.apache-antのインストール
http://ant.apache.org/にアクセスし、zip版をダウンロードする。
ダウンロードしたら任意のフォルダ(今回はProgram Files内)に展開する。
以下の環境変数を追加する。
ANT_HOME C:\Program Files\apache-ant-1.9.4
PATH C:\Program Files\apache-ant-1.9.4\bin
C:\> ant -version Apache Ant(TM) version 1.9.4 compiled on April 29 2014
上記のようになればインストール成功
2.build.xmlの作成
プロジェクト直下に以下の内容のbuild.xmlを作成する。
このとき、
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <project basedir="." default="dist" name=""> <!-- warファイルの設定 --> <property name="war.home" value="." /> <property name="web-app.name" value="appName" /> <!-- jarタスクによってwarファイルを作成 --> <target name="dist" > <war destfile="${war.home}/${web-app.name}.war" webxml="${war.home}/WEB-INF/web.xml"> <fileset dir="${war.home}" excludes="**/web.xml,**/WEB-INF/lib/**,${web-app.name}.war" /> </war> </target> </project>
pythonでwebアプリ(pythonインストールからDB接続まで)
pythonでwebアプリを作れる環境を作りたくて、bottle、mysql-connector-pythonを試してみた。
フレームワークは他にも有力なのがあるようでまだbottleでいくかは未決定。
OS:windows8 64bit
- pythonのインストール
https://www.python.org/downloads/
最新版のpython3.4.1をダウンロードして実行。python2に対し後方互換性がないようだが、
どんどん対応するライブラリが増えており、使いたいライブラリはすべてpython3に対応しているようなので、python3で決定。
インストールが完了したらc:\python34とc:\python\Scriptsへのパスを通しておく。
- pipのインストール
使ったことがないので便利さがわからないのだが、いろんなところにpythonとセットで書いてあるのでとりあえずインストールする。
setuptoolsから(https://pypi.python.org/pypi/setuptools)
環境に応じたez_setup.pyをダウンロードする。
python ez_setup.py easy_install pip
これで完了。
...もっと簡単にpipを入れる方法もある模様
http://qiita.com/who_you_me/items/831d62f396e6d66dda66
- エディタのインストール
何でもよいのだが評判が良いのでPyCharm Community Editionをインストール
http://www.jetbrains.com/pycharm/download/
日本語化されてないのが難点
- bottleのインストールと実行
pip install bottle
インストールしたら公式のチュートリアルに従って実行してみる
http://bottlepy.org/docs/dev/tutorial.html
from bottle import route, run @route('/hello') def hello(): return "Hello World!" run(host='localhost', port=8080, debug=True)
とりあえずこれでサーバーが立つのでhttp://localhost:8080/helloへアクセスして確認する。
サーバーはgunicornを使うとよいとのこと
DBは既存のmysqlを使いたいのでドライバが必要。
ドライバはいろいろありすぎるよう(参考:http://www.sakito.com/2012/10/python-mysql.html)
これといった性能要件もないのでmysql-connecter-pythonを使ってみることにした。
インストール
pip install mysql-connector-python
もし、--allow-externalをつけなさい、というようなエラーが出たら
pip install --allow-external mysql-connector-python mysql-connector-python
DBの方にはあらかじめテーブルを用意しておく。
以下は、DB:testのtable:table1から全データを持ってきて表示するサンプル
import mysql.connector connect = mysql.connector.connect(db="test", host="localhost", port=3306, user="****", passwd="****") cur=connect.cursor() cur.execute('select * from table1') rows = cur.fetchall() for row in rows: print(row) cur.close() connect.close()
- まとめ
とりあえず最低限動かすための準備はできた。
残りはやりたいことに対して必要な機能(テンプレートとかlogとか)の確認と、
そもそものフレームワークの選定。
他の候補としては実績が多いDjangoかBottleと同じく軽量なFlaskあたりを見てみる予定。